Агрегирование Django: суммирование умножения двух полей
У меня есть модель, вроде этой
class Task(models.Model):
progress = models.PositiveIntegerField()
estimated_days = models.PositiveIntegerField()
Теперь я хотел бы сделать расчет Sum(progress * estimated_days)
на уровне базы данных. Используя агрегирование Django, я могу получить сумму для каждого поля, но не суммирование умножения полей.
Ответы
Ответ 1
Обновление: для Django >= 1,8, пожалуйста, следуйте [email protected]
возможно использование Django ORM:
вот что вам следует делать:
from django.db.models import Sum
total = ( Task.objects
.filter(your-filter-here)
.aggregate(
total=Sum('progress', field="progress*estimated_days")
)['total']
)
Примечание: если два поля имеют разные типы, скажем integer
и float
, тип, который вы хотите вернуть, должен быть передан как первый параметр Sum
Это поздний ответ, но я думаю, это поможет кому-то искать то же самое.
Ответ 2
С Django 1.8 и выше вы можете передать выражение в свой агрегат:
from django.db.models import F
Task.objects.aggregate(total=Sum(F('progress') * F('estimated_days')))['total']
Также доступны константы, и все можно комбинировать:
from django.db.models import Value
Task.objects.aggregate(total=Sum('progress') / Value(10))['total']
Ответ 3
Решение зависит от версии Django.
-
django < 1,8
from django.db.models import Sum
MyModel.objects.filter(<filters>).aggregate(Sum('field1', field="field1*field2"))
-
django >= 1.8
from django.db.models import Sum, F
MyModel.objects.filter(<filters>).aggregate(Sum(F('field1')*F('field2')))
Ответ 4
У вас есть несколько вариантов:
Перезапись:
class Task(models.Model):
progress = models.PositiveIntegerField()
estimated_days = models.PositiveIntegerField()
progress_X_estimated_days = models.PositiveIntegerField(editable=False)
def save(self, *args, **kwargs):
progress_X_estimated_days = self.progress * self.estimated_days
super(Task, self).save(*args, **kwargs)