[Answered ]-Reducing the number of queries in Django

1👍

Use a model manager to always annotate AwardHolders

class AwardHolderQuerySet(models.QuerySet):
    def all(self):
        return self.annotate(Count('award__units_awarded'))

class AwardHolder(models.Model):
    name = models.CharField()
    objects = AwardHolderQuerySet.as_manager()
    ...

1👍

get_all_awards does not necessarily have to call get_total_awards. You’re repeating the same query for each entity instead of using a functionality Django already provides: annotate.

You can modify get_all_awards to use annotate and use get_total_awards only when the award applies to a single entity.

def get_all_awards():
    qs = AwardHolder.objects.annotate(sum=Sum('award__units_awarded'))
    awards = []
    for ah in qs:
        awards.append((ah, ah.sum))
    return awards

You may even drop the for loop and use the result from the queryset qs directly.

So you get the advantage of an optimized query when multiple objects and their related objects are being fetched, as opposed to running individual queries for each entity.

Leave a comment