Avoid extra
and raw
whenever possible. The aggregation docs have nearly this use case:
Straight from the docs:
# Each publisher, each with a count of books as a "num_books" attribute.
>>> from django.db.models import Count
>>> pubs = Publisher.objects.annotate(num_books=Count('book'))
>>> pubs
[<Publisher BaloneyPress>, <Publisher SalamiPress>, ...]
>>> pubs[0].num_books
73
So, to modify this for your particular example:
depts = Department.objects.
filter(product__review__time__range=["2012-01-01", "2012-01-08"]).
annotate(num_products=Count('product'))
The function calls on separate lines is just for readability and you should move them about accordingly. I haven’t tested this, but I think it should work.