Django聚集-零值除法 [英] Django Aggregate- Division with Zero Values
本文介绍了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
可以解决您的问题。annotate
与aggregate
几乎相同,不同之处在于它返回一个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屋!
查看全文