2016-08-04 8 views
2

によって加重AVGを注釈:margin=Avg('margin')加重平均を返すようにするためにジャンゴ - 私はSalesRecord上で動作し、次のモデルマネージャを持っているグループ

def by_variety_and_date(self, start_date, end_date): 
    return self.model.objects.filter(
     date__range=(start_date, end_date) 
    ).values(
     "variety" 
    ).annotate(
     qty_applied=Sum('qty_applied'), 
     margin=Avg('margin') 
    ) 

私が本当に欲しいことはベースであり、 qty_appliedにあります。 Djangoのannotate/aggregateクエリでこれを行う方法はありますか?私はこれの終わりまで.aggregate()をストリングすることで実験してきましたが、このクエリーセットで説明されているように平均でもvarietyが必要です。

この場合、モデルは次のようになります。

class Sale(models.Model): 
    margin = models.DecimalField(null=True, blank=True, decimal_places=2, max_digits=12) 
    qty_applied = models.IntegerField(null=True, blank=True) 
    variety = models.ForeignKey(Variety, null=True) 
    totals = Totals() 

EDIT

これは私が最後になってしまったものです。ちょっと怪しいですが、それはトリックです。 @WTowerが、それはqty_appliedだことにより、各オブジェクトのmarginを掛けるために提案されているよう私はFオブジェクトを使用

def by_variety_and_date(self, start_date, end_date): 
    return self.model.objects.filter(
     date__range=(start_date, end_date) 
    ).values(
     "variety" 
    ).annotate(
     qty_applied=Sum('qty_applied'), 
     profit=Sum('profit'), 
     cogs=Sum('cogs'), 
     sales=Sum('value'), 
     margin=Sum(
      (F('qty_applied')*F('margin')), output_field=FloatField() 
     )/Sum(
      'qty_applied', output_field=FloatField()) 
    ) 

、その後、Sumで全体を包み、グループ内のすべてのオブジェクトのqty_appliedSumことによってそれを割りました。魅力的な作品!

答えて

3

あなたは集約hereF() expression

>>> from django.db.models import F, FloatField, Sum 
>>> MyModel.objects.all().aggregate(
... w_avg=Sum((F('a')*F('b'))/F('b'), output_field=FloatField())) 

詳細を使用することができます。

また、カスタムSQL(ではなく、を推奨)またはカスタムメソッドをマネージャで使用することもできます。

+0

カスタムSQLは必要ありません:)。これはカスタムマネージャーメソッド、btwです。 –

関連する問題