Django 聚合:两个字段的乘积总和
- 2025-03-12 08:50:00
- admin 原创
- 28
问题描述:
我有一个类似这样的模型:
class Task(models.Model):
progress = models.PositiveIntegerField()
estimated_days = models.PositiveIntegerField()
现在我想Sum(progress * estimated_days)
在数据库级别进行计算。使用 Django Aggregation,我可以计算每个字段的总和,但不能计算字段乘积的总和。
解决方案 1:
使用 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']
解决方案 2:
更新:对于Django >= 1.8,请遵循@kmmbvnr 提供的答案
使用 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
这是一个迟来的回答,但我想它会对那些正在寻找同样问题的人有所帮助。
解决方案 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:
编辑(Django 1.8 之后)
从 Django 1.8 开始,你可以使用F
:
from django.db.models import F. Sum
total = (
Task
.objects
.aggregate(total=Sum(F('progress') * F('estimated_days')))
['total']
)
旧答案(Django 1.8 之前)
这个答案写于 2012 年,django 1.8 于 2015 年发布
您是否有几个选择:
原始查询
Emulbreh 未公开的方法
创建第三个字段
progress_X_estimated_days
,并在保存覆盖方法中更新它。然后通过这个新字段进行聚合。
覆盖:
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)
解决方案 5:
在您的模型中,您可以在定义执行计算的方法之前使用@property装饰器,如下所示:
class Task(models.Model):
progress = models.PositiveIntegerField()
estimated_days = models.PositiveIntegerField()
@property
def new_number(self):
new_number = self.progress * self.estimated_days
return new_number
然后,您可以正常访问它,例如在模板上调用 {{task.new_number}}。
相关推荐
热门文章
项目管理软件有哪些?
热门标签
云禅道AD