[Django]-Django Rest Framework custom ListSerializer only returning dictionary keys, not values

1👍

According to docs definition: The ListSerializer class provides the behavior for serializing and validating multiple objects at once.
You don’t typically need ListSerializers, if the data you pass could be represented as serializer data.
Suggested solution is to use nested serializers, if you dont get the key values from a model instance:

class ElementListSerializer(serializers.BaseSerializer):

    def to_representation(self, obj):
        return {
            'home': {"label_color": "#123456",
                     "label_text": "young"},
            'speak': {
                    "label_color": "",
                    "label_text": "Hello"}
        }

class ElementSerializer(serializers.ModelSerializer):

    element_list = ElementListSerializer() 

    class Meta:
        model = Element

    def create(self, validated_data):
        data = validated_data.pop('element_list')
        return data

1👍

The problem is in property data on ListSerializer which returns ReturnList instead of ReturnDict.

To fix your code, you have to change data property:

from rest_framework import serializers


class ElementListSerializer(serializers.ListSerializer):

    def to_representation(self, obj):
        result = {"home": {"label_color": "#123456","label_text": "young"},"speak": { "label_color": "","label_text": "Hello"}}
        return result

    @property
    def data(self):
        ret = serializers.BaseSerializer.data.fget(self)
        return serializers.ReturnDict(ret, serializer=self)


class ElementSerializer(serializers.ModelSerializer):
    class Meta:
        model = Element
        list_serializer_class = ElementListSerializer

    def to_representation(self, obj):
        result = super(ElementSerializer, self).to_representation(obj)
        return result

You can also create a more generic solution. It will automatically convert list of dicts with same structure to one dict where keys will be from specified field from child’s dict.

class ListToDictSerializer(serializers.ListSerializer):
    def to_representation(self, data):
        return {
            item[self.child.Meta.dict_serializer_key]: self.child.to_representation(item)
            for item in data
        }

    @property
    def data(self):
        ret = drf_serializers.BaseSerializer.data.fget(self)
        return serializers.ReturnDict(ret, serializer=self)


class MyModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = Model
        list_serializer_class = ListToDictSerializer
        dict_serializer_key = 'id'
👤jozo

Leave a comment