Django - 按组注释加权AVG

时间:2016-08-04 04:12:43

标签: django django-queryset

我有一个在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')
    )

我真正喜欢的是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()

修改

这就是我最终的结果。它有点不稳定,但它可以解决问题。

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

我使用@WTower建议的F对象将每个对象margin乘以它qty_applied,然后将整个事物包裹在{{1}中并将其除以组中所有对象的Sum的{​​{1}}。奇迹般有效!

1 个答案:

答案 0 :(得分:3)

您可以使用F() expression

$(document).on('change', 'your-selector', this.onChangeForAllElements);

onChangeForAllElements(e) {
   // console.log('onChange INVOKED', e);
}

有关汇总的更多信息here

或者,您可以在管理器中使用自定义SQL(推荐)或自定义方法。