web-dev-qa-db-ja.com

Django集計:2つのフィールドの乗算の合計

私はこのようなモデルを持っています

_class Task(models.Model):
   progress = models.PositiveIntegerField()
   estimated_days = models.PositiveIntegerField()
_

ここで、データベースレベルでSum(progress * estimated_days)計算を行いたいと思います。 Django Aggregationを使用すると、各フィールドの合計を取得できますが、フィールドの乗算の合計は取得できません。

46
Raunak Agarwal

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

注:2つのフィールドがintegerfloatなどの異なるタイプである場合、返されるタイプはSumの最初のパラメーターとして渡される必要があります。

遅い答えですが、同じものを探している人の助けになると思います。

69
sha256

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']
65
kmmbvnr

ソリューションは、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')))
    
24
Antstud

いくつかのオプションがありますか:

  1. 生のクエリ
  2. Emulbrehの文書化されていないアプローチ
  3. 3番目のフィールドを作成する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)
2
dani herrera