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.