У меня есть следующий менеджер модели, который работает на 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
всех объекты в группе. Работает как шарм!
Никакой пользовательский SQL не нужен :). Это метод настраиваемого менеджера, кстати. –