Django Rest Framework ListField and DictField

2020-02-05 07:02发布

问题:

I am having struggle with understanding ListField and DictField. I want to use it as a field on a serializer. I have a ListField which probably will contain many DictField. I tried to write a serializer as below:

class StopOncomingSerialier(serializers.Serializer):
    idn = serializers.IntegerField(read_only=True)
    buses = serializers.ListField(
        child=serializers.DictField(
            idn=serializers.IntegerField(read_only=True),
            stops_left=serializers.IntegerField(read_only=True)
        ),
    read_only=True
    )

I know, it does not make sense, since the documentation says DictField and ListField take child as argument. And so, the code above naturally raised error:

TypeError: __init__() got an unexpected keyword argument 'stops_left'

Desired Output

{
    "idn": 1,
    "buses": [
        {"idn": 11, "stops_left": 4},
        {"idn": 12, "stops_left": 15}
    ]
}

How to achieve this? buses is a list and might contain as many elements as I want.


Environment

  • python 3.5.1
  • django 1.9.6
  • django-rest-framework 3.3.3

回答1:

I think instead of doing that, you should use nested serializers.

Create a BusSerializer having fields idn and stops_left. Then include this serializer in your StopOncomingSerializer as buses field with many=True argument to handle multiple buses data.

class BusSerializer(serializers.Serializer):
    idn = serializers.IntegerField(read_only=True)
    stops_left = serializers.IntegerField(read_only=True)


class StopOncomingSerialier(serializers.Serializer):
    idn = serializers.IntegerField(read_only=True)
    buses = BusSerializer(many=True)