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

Django中如何在values()中获取当前语言的翻译字段?

解决Django TranslatableModel.values()获取当前语言翻译的问题

问题原因

直接在values()中使用certificate_name会报错,因为该字段并非存储在Certificate主表中,而是在关联的翻译表内;使用translations__certificate_name会返回所有语言的翻译记录,导致同一证书实例重复出现。

解决方案

方法1:使用Subquery获取优先语言翻译

通过子查询优先匹配当前语言的翻译,无对应翻译时回退到指定语言,确保每个证书仅返回一条记录:

from django.db.models import OuterRef, Subquery
from django.utils.translation import get_language

# 获取当前语言和回退语言
current_lang = get_language()
fallback_lang = "en"  # 替换为你的实际回退语言

# 构造子查询:优先取当前语言,再取回退语言
translation_subquery = (
    CertificateTranslation.objects.filter(
        master=OuterRef("pk"),
        language_code__in=[current_lang, fallback_lang]
    )
    .order_by("-language_code")  # 让当前语言结果排在前面,优先匹配
    .values("certificate_name")[:1]
)

# 主查询:通过annotate注入翻译字段,再用values提取所需字段
certificates_values_list = (
    Certificate.objects.filter(enabled=True)
    .annotate(certificate_name=Subquery(translation_subquery))
    .values("id", "type", "certificate_name")
)

方法2:使用Case-When条件判断

通过条件注解实现语言优先级匹配,配合distinct去重:

from django.db.models import Case, When, F, Value
from django.utils.translation import get_language
from django.db import models

current_lang = get_language()
fallback_lang = "en"

certificates_values_list = (
    Certificate.objects.filter(enabled=True)
    .annotate(
        certificate_name=Case(
            # 优先匹配当前语言的翻译
            When(translations__language_code=current_lang, then=F("translations__certificate_name")),
            # 无当前语言时使用回退语言
            When(translations__language_code=fallback_lang, then=F("translations__certificate_name")),
            # 都无匹配时使用默认空值
            default=Value(""),
            output_field=models.CharField(),
        )
    )
    .values("id", "type", "certificate_name")
    .distinct("id", "type", "certificate_name")
)

说明

  • 两种方法都能保证返回结果中每个证书仅出现一次,且优先使用当前语言翻译,无对应翻译时自动回退。
  • 注意替换代码中的fallback_lang为你项目实际配置的回退语言。

内容的提问来源于stack exchange,提问作者Hat hout

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 05:34:55