I'm trying to aggregate a list of integers from a model. The field that the integers are derived from are an @property decorator field. The decorator works as expected and within the template.html, if passed directly, displays without a problem. If however, I try and pass the @property field through .aggregate() the context passed into the template throws an error that basically says Cannot resolve keyword 'sum_thing' into field. followed by a list of model fields that don't include any of the decorator fields.
My question is - how do you aggregate (Sum) derived fields from the model?
#models.py
class Foo(models.Model):
a = 10 # a & b are both
b = 5 # models.IntegerField() items
@property
def sum_thing(self):
return self.a - self.b
#views.py
class Bar(generic.ListView):
def get_context_data(self, **kwargs):
qs = Foo.object.all()
totals = {}
totals['sumthing'] = qs.aggregate(total=Sum('sum_thing')
context = {
'totals': totals
}
return context
** I've greatly simplified the models.py and the views.py.
You can not aggregate using properties since it does not exist in the db. But, you can annotate your query with the help of Django's F expressions to get the actual value for those fields. See the example below.
from django.db.models import F, Sum
Foo.objects.annotate(sum_a_and_b=F('a') + F('b')).aggregate(total=Sum('sum_a_and_b'))
Also you can do any mathematical operation like / * + - with F, also you can do like this
.annotate(answer=F('a') + F('b') * 2)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With