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

Django自定义后台TranslatedFields多语言表单代码优化求助

问题

在Django项目中使用TranslatedFields实现多语言字段,整体功能正常,但自定义Admin面板时遇到重复代码问题。当前项目支持波斯语、英语2种语言,未来可能新增更多语言,目前在模板中硬编码各语言字段:

{{ form.short_description_fa|as_crispy_field }}
{{ form.short_description_en|as_crispy_field }}

为避免重复编写各语言字段,编写了如下模板标签:

def single_range(form, langs, index):
    c = len(langs)
    fields = []
    rng = range((index - 1) * c, (index - 1) * c + c)
    for f in rng:
        fields.append(list(form.fields.values())[f])
    return {
        'fields': fields
    }

模板中使用时:

{% for field in fields %}
    {{ field }}
    <br>
{% endfor %}

但输出结果为字段对象的字符串表示:

<django.forms.fields.CharField object at 0x7ff7fddcad50>
<django.forms.fields.CharField object at 0x7ff7fddc8b10>

希望找到无需重复代码的实现方法。

解决方案

方法1:动态渲染crispy-forms字段

直接输出字段对象无法触发表单字段的渲染逻辑,需要通过字段名获取表单的字段实例并应用as_crispy_field过滤器。

首先新增一个辅助模板标签,用于通过字段名获取表单字段:

from django import template

register = template.Library()

@register.filter
def get_field(form, field_name):
    return form[field_name]

然后修改原模板标签,返回多语言字段的名称列表:

def get_translated_fields(form, base_field, langs):
    # 生成对应语言的字段名,比如short_description_fa、short_description_en
    field_names = [f"{base_field}_{lang}" for lang in langs]
    # 过滤表单中实际存在的字段
    valid_fields = [name for name in field_names if name in form.fields]
    return {
        'field_names': valid_fields,
        'form': form
    }

模板中使用:

{% for field_name in field_names %}
    {{ form|get_field:field_name|as_crispy_field }}
    <br>
{% endfor %}

方法2:利用TranslationAdmin内置功能

如果是在Admin面板中使用,django-modeltranslation提供的TranslationAdmin类会自动处理多语言字段的渲染,无需手动编写模板代码。只需让你的Admin类继承该类:

from modeltranslation.admin import TranslationAdmin
from .models import YourModel

class YourModelAdmin(TranslationAdmin):
    # 配置其他Admin选项,比如list_display、fieldsets等
    pass

admin.site.register(YourModel, YourModelAdmin)

新增语言时,只要在项目配置中添加语言代码,Admin会自动渲染对应字段。

方法3:模板内直接筛选多语言字段

如果多语言字段遵循{base字段名}_{语言代码}的命名规则,可以在模板中直接遍历表单字段并筛选:

{% for field_name, field in form.fields.items %}
    {% if field_name.startswith "short_description_" %}
        {{ form[field_name]|as_crispy_field }}
        <br>
    {% endif %}
{% endfor %}

这种方式无需额外编写模板标签,新增语言时只要字段命名符合规则就会自动渲染。

内容的提问来源于stack exchange,提问作者mohammad javad

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 15:42:35