rectangletangle rectangletangle - 9 months ago 73
Python Question

Django's prefetch_related for count only

I have a situation something like this (the actual code is bound up in a template, and omitted for brevity).

threads = Thread.objects.all()
for thread in threads:

I've managed to considerably reduce the total number of queries using Django's awesome

threads = Thread.objects.prefetch_related('comments').prefetch_related('upvotes')

However I'm wondering if this situation could be further optimized. From what I understand
retrieves all of the data associated with the related models. Seeing as I only care about the amount of related models, and not about the models themselves, it seems like this query could be optimized further so that it doesn't retrieve a bunch of unnecessary data. Is there a way to do this in Django without dropping down to raw SQL?

Answer Source

You're right, it's wasteful to fetch all that data from the database if all you want to do is get the count. I suggest annotation:

threads = (Thread.objects.annotate(Count('comments', distinct=True))
                         .annotate(Count('upvotes', distinct=True)))
for thread in threads:

See the annotation documentation for more information.