2016-08-04 3 views
2

У меня есть следующий менеджер модели, который работает на SalesRecord:Джанго - Комментирование Weighted AVG группы

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

То, что я бы очень хотел это для margin=Avg('margin') вернуть средневзвешенное, на основе на qty_applied. Есть ли способ сделать это с помощью аннотатных/совокупных запросов Django? Я экспериментировал со строкой .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

Это то, что я, наконец, в конечном итоге с. Это немного неудобно, но это трюк.

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()) 
    ) 

Я использовал объекты F, как @WTower предложил умножить каждый объект margin по его qty_applied, затем завернул все это в Sum и разделить его на Sum в qty_applied всех объекты в группе. Работает как шарм!

ответ

3

Вы можете использовать F() 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())) 

Больше на агрегацию here.

В качестве альтернативы вы можете использовать пользовательский SQL (не) или пользовательский метод в менеджере.

+0

Никакой пользовательский SQL не нужен :). Это метод настраиваемого менеджера, кстати. –

Смежные вопросы