[英]Django Aggregation: Summation of Multiplication of two fields
I have a model something like this:我有一个这样的模型:
class Task(models.Model):
progress = models.PositiveIntegerField()
estimated_days = models.PositiveIntegerField()
Now I would like to do a calculation Sum(progress * estimated_days)
on the database level.现在我想在数据库级别做一个计算
Sum(progress * estimated_days)
。 Using Django Aggregation I can have the sum for each field but not the summation of multiplication of fields.使用 Django 聚合,我可以得到每个字段的总和,但不能得到字段乘法的总和。
With Django 1.8 and above you can now pass an expression to your aggregate:使用 Django 1.8 及更高版本,您现在可以将表达式传递给聚合:
from django.db.models import F
Task.objects.aggregate(total=Sum(F('progress') * F('estimated_days')))['total']
Constants are also available, and everything is combinable:常量也可用,一切都可以组合:
from django.db.models import Value
Task.objects.aggregate(total=Sum('progress') / Value(10))['total']
Update: for Django >= 1.8 please follow the answer provided by @kmmbvnr更新:对于Django >= 1.8,请按照@kmmbvnr 提供的答案进行操作
it's possible using Django ORM:可以使用 Django ORM:
here's what you should do:这是你应该做的:
from django.db.models import Sum
total = ( Task.objects
.filter(your-filter-here)
.aggregate(
total=Sum('progress', field="progress*estimated_days")
)['total']
)
Note: if the two fields are of different types, say integer
& float
, the type you want to return should be passed as the first parameter of Sum
注意:如果两个字段的类型不同,比如
integer
& float
,你要返回的类型应该作为Sum
的第一个参数传递
It's a late answer, but I guess it'll help someone looking for the same.这是一个迟到的答案,但我想它会帮助寻找相同答案的人。
The solution depends on Django version.解决方案取决于 Django 版本。
django < 1.8 Django < 1.8
from django.db.models import Sum MyModel.objects.filter(<filters>).aggregate(Sum('field1', field="field1*field2"))
django >= 1.8 Django >= 1.8
from django.db.models import Sum, F MyModel.objects.filter(<filters>).aggregate(Sum(F('field1')*F('field2')))
Do you have several options:你有几个选择:
progress_X_estimated_days
and update it in save overwrited method.progress_X_estimated_days
并在保存覆盖方法中更新它。 Then do aggregation through this new field. Overwriting:覆盖:
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)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.