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

如何在Django Rest Framework序列化器中翻译模型字段名?

解决DRF序列化器字段名根据用户语言动态翻译的问题

问题分析

你之前重写get_field_names的方式无法生效,核心原因是这个方法在类加载阶段就会执行,此时还没有请求上下文,无法根据当前用户的语言动态生成翻译后的字段名;而且提前将gettext_lazy转换为字符串会导致翻译值固定,不会随请求语言变化。

解决方案

1. 确保Django国际化配置正确

先检查项目settings.py中的配置:

USE_I18N = True

LANGUAGES = [
    ('en', 'English'),
    ('fr', 'French'),
]

# 配置翻译文件存放路径,确保该目录存在
LOCALE_PATHS = [
    BASE_DIR / 'locale',
]

# 确保中间件包含LocaleMiddleware,顺序要正确
MIDDLEWARE = [
    # ...其他中间件
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.locale.LocaleMiddleware',  # 放在SessionMiddleware之后、CommonMiddleware之前
    'django.middleware.common.CommonMiddleware',
    # ...其他中间件
]

2. 重写序列化器的to_representation方法

这个方法在请求处理阶段执行,能获取当前请求的语言环境,适合动态修改输出的字段名:

from django.utils.translation import gettext as _
from rest_framework import serializers
from .models import Post

class PostSerializer(serializers.ModelSerializer):
    class Meta:
        model = Post
        fields = ['title', 'about']

    def to_representation(self, instance):
        # 获取默认序列化结果
        data = super().to_representation(instance)
        # 动态替换字段名为翻译后的值
        translated_data = {}
        for field_name, value in data.items():
            # 针对需要翻译的字段做处理,其他字段保持原样
            if field_name == 'title':
                translated_key = _('title').lower()
                translated_data[translated_key] = value
            elif field_name == 'about':
                translated_key = _('about').lower()
                translated_data[translated_key] = value
            else:
                translated_data[field_name] = value
        return translated_data

如果需要翻译的字段较多,可以用映射表简化代码:

class PostSerializer(serializers.ModelSerializer):
    # 定义字段名与翻译键的映射
    FIELD_TRANSLATION_MAP = {
        'title': _('title'),
        'about': _('about'),
    }

    class Meta:
        model = Post
        fields = ['title', 'about']

    def to_representation(self, instance):
        data = super().to_representation(instance)
        translated_data = {}
        for field_name, value in data.items():
            # 优先使用翻译后的键,没有则保留原字段名
            translated_key = str(self.FIELD_TRANSLATION_MAP.get(field_name, field_name)).lower()
            translated_data[translated_key] = value
        return translated_data

3. 生成并编译翻译文件

在项目根目录执行以下命令生成法语翻译文件:

# 生成法语翻译模板
python manage.py makemessages -l fr
# 编译翻译文件
python manage.py compilemessages

打开locale/fr/LC_MESSAGES/django.po文件,添加对应翻译:

msgid "title"
msgstr "titre"

msgid "about"
msgstr "à propos"

编译后,当请求的语言为法语时,接口返回的字段名会变成titre和à propos(小写);英语环境下则保持title和about。

关于第三方包的说明

你尝试的几个第三方包主要针对字段值的翻译,而非字段名的动态替换,因此无法直接满足需求。自己通过重写to_representation的方式更直接可控。

内容的提问来源于stack exchange,提问作者Jaweher Ben Salah

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 16:12:43