Django聚集-零值除法 [英] Django Aggregate- Division with Zero Values

查看:17
本文介绍了Django聚集-零值除法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用Django的aggregate query expression将一些值相加。最后一个值是除法表达式,有时可能以零作为分母。如果是这种情况,我需要一种转义方法,以便它只返回0。

我尝试了以下方法,因为我一直在使用类似的注释表达式:

from django.db.models import Sum, F, FloatField, Case, When

def for_period(self, start_date, end_date):
    return self.model.objects.filter(
        date__range=(start_date, end_date)
    ).aggregate(
        sales=Sum(F("value")),
        purchase_cogs=Sum(F('purchase_cogs')),
        direct_cogs=Sum(F("direct_cogs")),
        profit=Sum(F('profit'))
    ).aggregate(
        margin=Case(
            When(sales=0, then=0),
            default=(Sum(F('profit')) / Sum(F('value')))*100
        )
    )

但是,它显然不起作用,因为正如错误所说:

"dict"对象没有"Aggregate"属性

处理此问题的正确方式是什么?

推荐答案

这显然行不通;因为aggregate返回的是字典,而不是查询集(请参阅docs),所以您不能将两个aggregate调用链接在一起。

我认为使用annotate可以解决您的问题。annotateaggregate几乎相同,不同之处在于它返回一个QuerySet,其中包含另存为属性的结果,而不是返回字典。结果是您可以链接annotate调用,甚至调用annotate然后aggregate

所以我相信是这样的:

return self.model.objects.filter(
    date__range=(start_date, end_date)
).annotate(  # call `annotate`
    sales=Sum(F("value")),
    purchase_cogs=Sum(F('purchase_cogs')),
    direct_cogs=Sum(F("direct_cogs")),
    profit=Sum(F('profit'))
).aggregate(  # then `aggregate`
    margin=Case(
        When(sales=0, then=0),
        default=(Sum(F('profit')) / Sum(F('value')))*100
    )
)

应该可以工作。

希望这对您有帮助。

这篇关于Django聚集-零值除法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆