Как суммировать по вычисленной переменной в Джанго?


April 2019


27 раз


У меня неприятности найти решение следующей простой задачи. Следующая команда

tenta_data = Konstruktion.objects.all().annotate(tid=Sum(F('antal')))

работает отлично, если Антал является переменной в базе данных:

class Konstruktion(models.Model):
    antal = models.FloatField()
    def anumber(self):
       return .....

но как мне делать, если я хочу просуммировать anumber? Какая функция.

2 ответы


Well the database has no knowledge about functions, properties, etc. So that means it can not automate this task for you.

The only way you can do this is to calculate it at the Python level, like for example:

total_anumbers = sum(
    for k in Konstruktion.objects.all()

This will sum(..) up the values by iterating over the Konstruktion objects, and each time calculating the k.anumber() and sum these up.

Note that the Python sum works slightly different than the Python equivalent. It will for example not ignore the NULL/None values. Furthermore it can add different type of objects together (like bools with ints, etc., given such addition is implemented).

Other more advanced aggregates are usually even harder to mimic at the Python level.


As @Willem Van Onsem said, you can't aggregate over model properties/functions. But, you can annotate them as below (if the function does some simple math).

So, I assume the function return sum of two fields,

class Konstruktion(models.Model):
    antal = models.FloatField()
    second_field = models.FloatField()

    def anumber(self):
        return self.antal + self.second_field

Then the aggregation would be like below,

from django.db.models import F, Sum

Konstruktion.objects.annotate(sum=F('antal') + F('second_field')).aggregate(Sum('sum'))