We have two models (simplified versions):
class Contestant(models.Model):
email = models.EmailField(max_length=255, unique=True)
# plus some other fi
When your aim is to add aggregated values to each item, you should use annotate, instead of aggregate
.
For example (a simple query, no additional methods required):
Contestant.objects.filter(...).annotate(total_points=Sum('points__value'))
If you really want to put this code out of your query: you can, but a model method is not a right way to do this. Methods on models are for operations on single instances. If you want to do something on a whole QuerySet use an ORM Manager instead.
With a Manager this would look like this:
class TotalPointsManager(models.Manager):
def get_queryset(self):
return super(TotalPointsManager, self).get_queryset().annotate(total_points=Sum('points__value'))
class Contestant(models.Model):
email = models.EmailField(max_length=255, unique=True)
objects = TotalPointsManager() # You are overriding the default manager!
and then you would construct your query as usual (you can drop prefetch_related
):
Contestant.objects.filter(...)
...and total_points
field would become "magically" available for every object.