Specifying get methods for nested serializers

In the case of nested serializers, is there a way to specify a method that will get the data?

class AuthorSerializer(ModelSerializer):
....

class BookSerializer(ModelSerializer):
    authors = AuthorSerializer(many=True)
....

In this example, I would like to intercept and modify how BookSerializer gets the authors. How do I accomplish this?

you can use a SerializerMethodField to override how the authors field is retrieved instead of directly using AuthorSerializer(many=True) you define a method in BookSerializer that fetches and processes the authors

you can write you BookSerializer like this:

from rest_framework import serializers

class AuthorSerializer(serializers.ModelSerializer):
    class Meta:
        model = Author
        fields = "__all__"

class BookSerializer(serializers.ModelSerializer):
    authors = serializers.SerializerMethodField()

    class Meta:
        model = Book
        fields = "__all__"

    def get_authors(self, obj):
        # Customize how the authors are retrieved
        authors = obj.authors.all()  # modify the logic as per your need here
        return AuthorSerializer(authors, many=True).data

If you want to filter, you typically don't do this in the serializer, but in the ViewSet, like:

from django.db.models import Prefetch
from rest_framework import viewsets


class BookViewSet(ModelViewSet):
    serializer_class = BoolSerializer
    queryset = Book.objects.prefetch_related(
        Prefetch('authors', Author.objects.filter(is_alive=True))
    )

This will also boost performance significantly, because all Authors are fetche in one additional query.

Back to Top