You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django如何按币种规则实现Permit模型按月汇总求和的ORM查询

实现方案

你可以使用Django的Case/When条件表达式一次性完成所有币种的计算和月度汇总,不需要拆分两次查询,逻辑和你模型中定义的euro_value属性完全对齐,性能也更好。

第一步:导入依赖包

from django.db.models import Case, When, F, Sum, DecimalField
from django.db.models.functions import Round
import calendar

如果你的Django版本低于3.2,没有内置Round函数,可以跳过导入,最后格式化数据时再做四舍五入处理。

第二步:执行统计查询

# 替换为你实际需要查询的年份
target_year = 2024

monthly_total = Permit.objects.filter(
    info__date_of_transaction__year=target_year,
    # 过滤空值避免计算错误
    volume__isnull=False,
    unit_price__isnull=False,
    ex_rate__isnull=False
).annotate(
    # 按币种规则计算单条记录的欧元价值,保留两位小数
    euro_value = Round(
        Case(
            When(currency='USD', then=F('volume') * F('unit_price') / F('ex_rate')),
            default=F('volume') * F('unit_price') * F('ex_rate'),
            output_field=DecimalField()
        ),
        2
    )
).values(
    'info__date_of_transaction__month'
).annotate(
    total = Sum('euro_value')
).order_by('info__date_of_transaction__month')

第三步:转换为期望的输出格式

labels = []
data = []
for item in monthly_total:
    # 把月份数字转为英文名称
    labels.append(calendar.month_name[item['info__date_of_transaction__month']])
    # 数值转为两位小数字符串
    data.append(f"{item['total']:.2f}")

result = {"labels": labels, "data": data}

如果没有使用Round函数,把数值格式化的行替换为以下代码即可:

data.append(f"{round(item['total'], 2):.2f}")

内容的提问来源于stack exchange,提问作者Oppong Ntiamoah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 01:45:02