how to add annotate data in django-rest-framework queryset responses?

The accepted solution will hit the database as many times as results are returned. For each result, a count query to the database will be made.

The question is about adding annotations to the serializer, which is way more effective than doing a count query for each item in the response.

A solution for that:

models.py

class Author(models.Model):
    name = models.CharField(...)
    other_stuff = models...
    ...

class Book(models.Model):
    author = models.ForeignKey(Author)
    title = models.CharField(...)
    publication_year = models...
    ...

serializers.py

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

    class Meta:
        model = Book
        fields = ('id', 'title', 'authors')

views.py

class BookViewSet(viewsets.ModelViewSet):
    queryset = Book.objects.annotate(authors=Count('author'))
    serializer_class = BookSerializer
    ...

That will make the counting at database level, avoiding to hit database to retrieve authors count for each one of the returned Book items.

Leave a Comment