Reputation: 635
I want to annotate a count of objects to a queryset, which I know how to do, but I want the objects counted to have their own filtering.
This works well;
first_model_qs = FirstModel.objects.filter(do a bunch of filtering)
grouped_values_qs = first_model_qs.values('second_model').annotate(Count('pk'))
So I now have a nice queryset with all the first_model
counts grouped by second_model
ids. Awesome.
What I'd like to do now is something like;
secound_model_qs = SecondModel.objects.annotate(first_model_count = grouped_values_qs)
And then be able to say secound_model_qs.first().first_model_count
Is this possible?
Upvotes: 1
Views: 5597
Reputation: 16020
I think you can do it with a Subquery and more specifically by Using aggregates within a Subquery expression
from django.db.models import OuterRef, Subquery, Count
first_model_query = (FirstModel.objects
# Do the filtering
.filter(second_model=OuterRef('pk'))
# add grouping
.values('second_model')
# do the aggregation
.annotate(cnt=Count('pk'))
# now return only a single column
.values('cnt')
)
secound_model_qs = SecondModel.objects.annotate(
first_model_count=Subquery(first_model_query)
)
Upvotes: 3