如何使用Django统计活跃与非活跃投资的余额总和?现有查询代码无法正常运行
如何正确统计活跃与非活跃投资的余额总和
嘿,我看了你的代码和Investment模型结构,问题主要出在两个地方:字段对应错误,以及没处理聚合结果为空的情况。咱们一步步来解决:
问题根源
你要统计的是locked_total_balance(锁定总余额)和total_available_balance(可用总余额),但原代码存在两处偏差:
- 统计锁定余额时用了
Sum('balance'),但你的模型里专门有locked_balance字段才是锁定余额的存储字段 - 当没有符合条件的投资记录时,
aggregate()会返回{'total_balance': None},直接使用这个值很容易触发类型错误
修正后的基础代码
直接匹配正确字段,并处理空值情况:
# 统计活跃投资的锁定总余额:筛选is_active=True的记录,求和locked_balance字段 locked_total_balance = Investment.objects.filter(is_active=True).aggregate(total=Sum('locked_balance'))['total'] or 0 # 统计非活跃投资的可用总余额:筛选is_active=False的记录,求和balance字段 total_available_balance = Investment.objects.filter(is_active=False).aggregate(total=Sum('balance'))['total'] or 0
关键说明
- 字段匹配:把
Sum('balance')替换成Sum('locked_balance'),才对应你要的锁定余额总和需求 - 空值处理:添加
or 0是为了避免无匹配记录时返回None,确保结果始终是整数,防止后续计算报错 - 键名调整:把聚合结果的键改成
total只是为了简洁,你也可以保持total_balance,只要取值时对应上即可
进阶优化(减少数据库查询)
如果想一次查询搞定两个统计值,减少数据库请求次数,可以用Django的条件聚合功能:
from django.db.models import Sum, Case, When, IntegerField # 一次查询获取两个统计结果 balance_stats = Investment.objects.aggregate( locked_total_balance=Sum( Case( When(is_active=True, then='locked_balance'), default=0, output_field=IntegerField() ) ), total_available_balance=Sum( Case( When(is_active=False, then='balance'), default=0, output_field=IntegerField() ) ) ) # 取出最终结果 locked_total_balance = balance_stats['locked_total_balance'] total_available_balance = balance_stats['total_available_balance']
这种方式只需要一次数据库请求,在数据量较大时性能会更优。
内容的提问来源于stack exchange,提问作者Thaddeaus Iorbee
相关产品推荐
相关产品推荐

