如何在Django ORM查询中对Sum聚合结果保留两位小数
Django ORM Sum聚合结果四舍五入保留小数解决方法
问题根因
直接调用Python内置round()函数不生效,是因为Sum('aantal')属于Django查询表达式,并非实际计算后的数值,Python原生函数无法对其做运算,也不会被自动翻译为数据库层面的ROUND函数,因此聚合逻辑不会按预期执行。
解决方案
方案1:使用Django内置Round函数(Django 3.2+ 适用)
Django 3.2及以上版本已内置数据库层面的Round函数,直接导入使用即可:
from django.db.models import Sum, Round verloningsoverzicht_cumulatief_dagen = Overzicht.objects.filter(periode=periode, jaar=jaar) \ .values('testcontract', 'contract') \ .annotate(aantal=Round(Sum('aantal'), 2))
方案2:自定义Round函数(低版本Django适用)
如果使用的Django版本低于3.2,可自行封装Func表达式调用数据库的ROUND函数:
from django.db.models import Sum, Func # 自定义Round函数 class Round(Func): function = 'ROUND' arity = 2 verloningsoverzicht_cumulatief_dagen = Overzicht.objects.filter(periode=periode, jaar=jaar) \ .values('testcontract', 'contract') \ .annotate(aantal=Round(Sum('aantal'), 2))
该方案适配MySQL、PostgreSQL等主流数据库,特殊数据库可根据语法调整function属性值。
方案3:Python层面处理结果
如果查询结果量较小,也可以在拿到查询结果后,遍历每条数据做四舍五入处理:
for item in verloningsoverzicht_cumulatief_dagen: item['aantal'] = round(item['aantal'], 2)
内容的提问来源于stack exchange,提问作者Sander
相关产品推荐
相关产品推荐

