Django的聚合:两个领域的乘法求和(Django Aggregation: Summation

2019-06-17 22:30发布

我有一个模型,像这样的一些事情

class Task(models.Model):
   progress = models.PositiveIntegerField()
   estimated_days = models.PositiveIntegerField()

现在,我愿做一个计算Sum(progress * estimated_days)在数据库级别上。 使用Django聚合我可以为每个字段的总和,但并不领域的乘法运算的总和。

Answer 1:

更新: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']
         )

注:如果这两个领域是不同类型的,比如integerfloat ,要返回类型应的第一个参数传递Sum

这是一个迟到的回答,但我想它会帮助别人寻找相同。



Answer 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']


Answer 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'))) 


Answer 4:

你有几种选择:

  1. 原始查询
  2. Emulbreh的无证方法
  3. 创建第三场progress_X_estimated_days和更新它保存overwrited方法。 那么就通过这一新领域聚集。

覆盖:

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)


文章来源: Django Aggregation: Summation of Multiplication of two fields