Reputation: 11523
lets say I have a model Comments and another model Answers. I want to query all comments but also include in the query the number of answers each comment has. I thought annotate()
would be useful in this case, but I just don't know how to write it down. The docs write that:
New in Django 1.8: Previous versions of Django only allowed aggregate functions to be used as annotations. It is now possible to annotate a model with all kinds of expressions.
So. This is an example of my models:
class Comment(models.Model):
...
class Answer(models.Model):
comment = models.ForeignKey(Comment, related_name='answers')
And this is an example query:
queryset = Comment.objects.all().annotate(...?)
I'm not sure how to annotate the Count
of answers each comment has. That is, how many answers point to each comment on the FK field comment
. Is it even possible? is there a better way? Is it better to just write a method on the manager?
Upvotes: 9
Views: 8615
Reputation: 673
A better solution would be:
from django.db.models import Prefetch, QuerySet, Count
def get_queryset(self) -> QuerySet[Customer]:
return (
Comments.objects
.prefetch_related(
Prefetch('answers', queryset=Answer.objects.only('id')),
)
.annotate(
answers_count=Count('answers', distinct=True),
)
.order_by("-id")
)
Please adjust according to specific scenario.
Upvotes: 0
Reputation:
You need to use a Count
aggregation:
from django.db.models import Count
comments = Comments.objects.annotate(num_answers=Count('answers'))
Upvotes: 22