
在构建支持多语言的django网站时,经常会遇到需要翻译模型中charfield或integerfield字段的choices选项值的情况。直接在模板中使用{% blocktranslate %}{{ variable }}{% endblocktranslate %}来翻译动态变量(如each_order.status)往往无法达到预期效果,因为blocktranslate期望的是静态字符串或已标记为可翻译的字符串。django为此提供了更为优雅和推荐的解决方案,即结合使用textchoices、gettext_lazy和get_foo_display方法。
当模型字段定义了choices选项时,例如:
class Order_product(models.Model):
# ...
status = models.CharField(max_length = 255, choices = [('Pending', 'Pending'), ('Need-Delivery', 'Need-Delivery'), ...])在模板中直接显示{{ each_order.status }}会输出原始的英文值(如'Pending')。如果尝试用blocktranslate包裹它,Django的makemessages工具可能会生成一个包含%(each_order.status)s的msgid,这表明它将变量视为一个插值,而不是一个可以直接翻译的字符串,导致翻译失效。
Django 3.0及更高版本推荐使用TextChoices(或IntegerChoices)来定义模型字段的选项。这种方式不仅使代码更具可读性,还与Django的国际化(i18n)功能更好地集成。
首先,我们需要在模型中定义可翻译的choices。这通过django.utils.translation.gettext_lazy(通常别名为_)来实现。gettext_lazy会延迟翻译字符串,直到它们被实际使用时,这对于模型定义非常重要,因为它避免了在应用启动时就加载所有翻译。
修改 models.py 如下:
from django.db import models
from django.utils.translation import gettext_lazy as _
class OrderStatus(models.TextChoices):
PENDING = "Pending", _("Pending")
NEED_DELIVERY = "Need-Delivery", _("Need-Delivery")
DELIVERY = "Delivery", _("Delivery")
SUCCESS = "Success", _("Success")
RETURN_ORDER = "Return-Order", _("Return-Order")
CANCEL = "Cancel", _("Cancel")
class Order_product(models.Model):
name = models.CharField(max_length=255)
note = models.TextField()
status = models.CharField(
max_length=255,
choices=OrderStatus.choices,
default=OrderStatus.PENDING # 可以设置默认值
)
def __str__(self):
return f"{self.name} - {self.get_status_display()}"在上述代码中:
Django模型实例提供了一个便捷的方法来获取choices字段的“人类可读”表示,这个方法命名约定是get_FOO_display,其中FOO是字段的名称。例如,对于status字段,这个方法就是get_status_display()。这个方法会自动返回当前活动语言环境下的翻译值。
修改 test.html 如下:
{% load i18n %} {# 确保加载i18n标签 #}
{% for each_order in get_order %}
<p>
{{ each_order.get_status_display }}
</p>
{% endfor %}注意,这里不再需要{% blocktranslate %}标签,因为get_status_display方法本身就负责返回已翻译的字符串。
views.py 中的逻辑无需改变,因为它只是简单地获取模型实例并传递给模板:
from django.shortcuts import render
from .models import Order_product # 导入具体的模型
def test(request):
get_order = Order_product.objects.all()
return render(request, 'test/test.html', {'get_order': get_order})完成上述修改后,需要更新Django的翻译文件:
python manage.py makemessages -l vi # 替换'vi'为你的目标语言代码
执行此命令后,在locale/vi/LC_MESSAGES/django.po文件中,你会找到类似这样的条目:
msgid "Pending" msgstr ""
msgid "Pending" msgstr "待处理" # 越南语可能是 "Đang chờ" 或其他
msgid "Success" msgstr "成功" # 越南语可能是 "Thành công"
python manage.py compilemessages
确保你的settings.py中包含了LocaleMiddleware,它是处理语言切换的关键:
# settings.py
MIDDLEWARE = [
# ...
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.locale.LocaleMiddleware', # 确保在 SessionMiddleware 之后,CommonMiddleware 之前
'django.middleware.common.CommonMiddleware',
# ...
]
# 定义支持的语言
LANGUAGES = [
('en', _('English')),
('vi', _('Vietnamese')),
# ... 其他语言
]
# 定义翻译文件查找路径
LOCALE_PATHS = [
BASE_DIR / 'locale',
]通过采用TextChoices结合get_FOO_display的方法,Django开发者可以高效且优雅地实现模型choices字段的国际化,确保在多语言环境下用户能够看到正确翻译的选项值。这种方法避免了在模板中直接处理动态翻译的复杂性,使代码更加清晰和易于维护。
以上就是Django中模型Choices字段的动态翻译实践指南的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号