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

Django如何动态设置annotate中Case的When条件then值?

问题描述

我有一个葡萄牙语月份字典:

MONTHS = {
    1: "Janeiro",
    2: "Fevereiro",
    3: "Março",
    4: "Abril",
    5: "Maio",
    6: "Junho",
    7: "Julho",
    8: "Agosto",
    9: "Setembro",
    10: "Outubro",
    11: "Novembro",
    12: "Dezembro",
}

需要在Django QuerySet里通过annotate把last_installment_month字段的数字值转换成对应的月份字符串。目前用Case+When的写法是手动逐个写条件:

queryset = queryset.annotate(
    last_installment_month_as_string=Case(
        When(last_installment_month=1, then=Value(MONTHS[1])),
        When(last_installment_month=2, then=Value(MONTHS[2])),
        When(last_installment_month=3, then=Value(MONTHS[3])),
        When(last_installment_month=4, then=Value(MONTHS[4])),
        When(last_installment_month=5, then=Value(MONTHS[5])),
        When(last_installment_month=6, then=Value(MONTHS[6])),
        When(last_installment_month=7, then=Value(MONTHS[7])),
        When(last_installment_month=8, then=Value(MONTHS[8])),
        When(last_installment_month=9, then=Value(MONTHS[9])),
        When(last_installment_month=10, then=Value(MONTHS[10])),
        When(last_installment_month=11, then=Value(MONTHS[11])),
        When(last_installment_month=12, then=Value(MONTHS[12])),
    )
)

但想通过循环动态生成这些When条件,尝试了下面的写法但无效:

for key, value in MONTHS.items():
    queryset = queryset.annotate(
    last_installment_month_as_string=Case(
        When(last_installment_month=key, then=Value(value)) 
    )
)

求正确的动态生成方式。

解决方案

你之前的循环写法每次都会重复覆盖last_installment_month_as_string注解,且每次仅生成单个When条件,因此无法实现预期效果。正确的做法是先一次性生成所有When对象的列表,再将这个列表传入Case:

from django.db.models import Case, When, Value

# 遍历MONTHS生成所有When条件
when_conditions = [
    When(last_installment_month=key, then=Value(value))
    for key, value in MONTHS.items()
]

# 将条件列表拆包传给Case,完成注解
queryset = queryset.annotate(
    last_installment_month_as_string=Case(*when_conditions)
)

补充说明

  • 使用列表推导式批量生成When实例,确保每个数字月份都对应正确的字符串值
  • 用*运算符将列表拆包为Case的参数,效果与手动编写12个When完全一致
  • 若需要处理last_installment_month为空的场景,可以给Case添加default参数,例如default=Value("")

内容的提问来源于stack exchange,提问作者Ives Furtado

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 19:30:34