'Prefetch not working for ForeignKey's related_name? (Results in n + 2 queries)

# models.py

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

class Book(models.Model):
  title = CharField()
  author = ForeignKey(Author, related_name="books")


# serializer.py

class BookSerializer(serializers.ModelSerializer):
  class Meta:
    model = Book
    fields = ["id", "title"]

class AuthorSerializer(serializers.ModelSerializer):
  books = serializers.SerializerMethodField()

  class Meta:
    model = Author
    fields = ["id", "name", "books"]

  def get_books(self, obj):
    qs = obj.books
    return BookSerializer(qs, many=True).data


# views.py

class AuthorListView(generics.ListAPIView):
  queryset = Author.objects.all().prefetch_related("books")
  serializer_class = AuthorSerializer

Seems relatively straightforward but I'm still getting n + 2 queries?

I would expect to get just 2 queries - one for all the authors and one for all the books?

If I actually simplify my view's queryset to just Author.objects.all(), I get n + 1 queries.

Edit

If I setup a BookListView instead where the queryset = Book.objects.all().select_related("author"), it prefetches fine and the resulting page is just 1 query.



Solution 1:[1]

Ah, never mind. I was actually ordering my books in my Serializer method which was adding the additional queries:

  def get_books(self, obj):
    qs = obj.books.order_by(XXX)
    return BookSerializer(qs, many=True).data

If I remove that ordering, it is indeed just two queries.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Chris