Vishal Rao
Vishal Rao

Reputation: 912

Override to_representation in List serializer class

I have a serializer that implements the BaseSerializer class in which I'm using the to_representation function to do a function call like so:

class ItemSerializer(serializers.BaseSerializer):
    def to_representation(self, instance):
        ret = super().to_representation(instance)
        ret['log'] = SERVICE.log(instance.id)
        return ret

    class Meta:
        list_serializer_class = ItemListSerializer
        model = models.Item
        fields = '__all__'

I also have a list serializer for the same ItemListSerializer which looks like this:

class ItemListSerializer(serializers.ListSerializer):
    def create(self, validated_data):
        items = [models.Item(**item) for item in validated_data]
        return models.Item.objects.bulk_create(items)

What I want to do is override the to_representation method in the ItemSerializer for when I want to get the entire list of Items. I basically want to avoid doing a function call per item and instead do a bulk call for all the items when the list of items is requested for performance reasons.

Is there a good way to do this? I followed these docs for creating the ItemListSerializer:https://www.django-rest-framework.org/api-guide/serializers/#customizing-listserializer-behavior but it only talks about overriding create and update methods.

Upvotes: 8

Views: 9753

Answers (1)

Kamil Niski
Kamil Niski

Reputation: 4765

You can access all items in ListSerializer.to_representation

It should be a good place to do what you want.

The method looks like this:

def to_representation(self, data):
    """
    List of object instances -> List of dicts of primitive datatypes.
    """
    # Dealing with nested relationships, data can be a Manager,
    # so, first get a queryset from the Manager if needed
    iterable = data.all() if isinstance(data, models.Manager) else data

    return [
        self.child.to_representation(item) for item in iterable
    ]

But to be honest I don't see what would you gain from it. Your use case looks like it will be no measurable performance boost.

Upvotes: 8

Related Questions