2012-08-28 24 views
30

の乗算の総和が、私はこのジャンゴ集計:二つのフィールド

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

のようないくつかの事は今私は、データベースレベルで計算Sum(progress * estimated_days)をしたいと思っモデルを持っています。 Django Aggregationを使うと、各フィールドの合計を持つことができますが、フィールドの乗算の合計はできません。

答えて

60

更新:ジャンゴ> = 1.8ためそれはDjangoのORMを使用して可能です@kmmbvnr

が提供する答えに従ってください。

ここ何する必要があります:

from django.db.models import Sum 

total = (Task.objects 
      .filter(your-filter-here) 
      .aggregate(
       total=Sum('progress', field="progress*estimated_days") 
      )['total'] 
     ) 

注:2つのフィールドが異なるタイプのものであれば、integer & float言う、あなたが返すようにしたいタイプは、それは後半の答えですが、私はそれがますねSum

の最初のパラメータとして渡す必要があります同じものを探している人を助けてください。ジャンゴ1.8とあなたが今、あなたの集計に式を渡すことができます上記で

+1

うまく動いていますが、* field * kwargが文書化されておらず、Djangoテストスイートでそれに関するテストが見つかりませんでした。 –

+0

これはクールです!それはまだdjango 1.7で動作します。 – haudoing

+0

「進捗状況」フィールドは何を達成していますか?私はこのコードスニペットを理解しようとしています。なぜならそれは必要なものだからです。 – Maor

2

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

  1. Raw query
  2. Emulbreh's undocumented approach
  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) 
+0

ええ、私は実際に生のSQLまたはなどの追加の属性を保っていました最後のオプション。とにかく、ありがとう。 –

35

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'] 
+0

私はこの答えが理解して維持するのが簡単だと思います。これらのフィールドの型が異なる場合は、 'output_field'パラメータを集計関数に追加してください。 –

+4

これは現在の正解です。ありがとう –

+1

私はdjango 1.7でそれを試していますが、AttributeError 'AttributeError: 'ExpressionNode'オブジェクトに属性 'split''がありません。私のdjangoバージョンが1.7.10であるバージョン –

10

ソリューションは、Djangoのバージョンに依存します。

  • ジャンゴ< 1.8

    from django.db.models import Sum 
    MyModel.objects.filter(<filters>).aggregate(Sum('field1', field="field1*field2")) 
    
  • ジャンゴ> = 1.8

    from django.db.models import Sum, F 
    MyModel.objects.filter(<filters>).aggregate(Sum(F('field1')*F('field2')))