我有一个模板:
{% trans "Log out" %}
这是由Django自动翻译为Terminarsesión的西班牙语。但是,我想将其翻译为Cerrarsesión。
我曾尝试将此文字添加到.po文件中,但是当我编译邮件时,我收到一条错误,说这个文字是重复的。
有没有办法更改/覆盖默认的Django翻译?
感谢。
答案 0 :(得分:26)
这对我有用:
在您的app文件夹中创建一个文件,该文件将保存需要覆盖翻译的django消息,例如: django_standard_messages.py
django.po
文件中的找到需要覆盖的消息(字符串),例如django.forms/fields.py
有消息_(u"This field is required.")
,我们希望将其转换为德语
django_standard_messages.py
中添加所有此类消息:
# coding: utf-8 _ = lambda s: s django_standard_messages_to_override = [ _("This field is required."), ... ]
makemessages
,compilemessages
) - makemessages将在您的应用程序.po文件中添加添加的django标准消息,找到并翻译,运行compilemessages以更新.mo文件 背后的逻辑:(我认为;)) - 当 ugettext
函数搜索一条消息(字符串)的翻译时,有几个{{1需要搜索的/ .po
个文件。 使用第一个匹配。因此,如果我们的本地应用.mo
/ .po
按此顺序排在第一位,我们的翻译将覆盖所有其他应用(例如django默认值)。
当您需要翻译所有或大部分django默认消息时,另一种可能性(我没有尝试)是复制我们的语言环境或其他特殊文件夹中的默认django .mo
文件,修复翻译并将.po
django LOCALE_PATHS
文件中的文件夹(如果是新文件)注册为列表中的第一个条目。
背后的逻辑:与上一节中提到的非常相似。
答案 1 :(得分:5)
最简单的方法是收集django.contrib.admin语言环境文件夹中找到的.po文件并重新编译它(您可以使用POEdit执行此操作)。
您还可以通过将django.contrib.admin模板放入项目模板文件夹(例如:yourproject / templates / admin / change_form.html),然后从项目根目录运行makemessages来覆盖django.contrib.admin模板(尽管不再支持对于django 1.4 alpha,如果我是正确的)
编辑:Robert Lujo的回答是干净的方法
答案 2 :(得分:5)
基于Robert Lujo answer,他的选择完全正常。并且IMO更简单(仅将覆盖的语言环境保留在特殊的.po文件中)。以下是步骤:
为LOCALE_PATHS Django设置添加额外路径。
LOCALE_PATHS =(
#默认值,makemessages命令将生成文件 os.path.join(BASE_DIR,'myproject','locale'),
#our new,extended locale目录
os.path.join(BASE_DIR,'myproject','locale_extra'), )
找到要翻译的原始Django(或第三方)字符串
msgstr“最近的行动” msgstr“最后的行动”
答案 3 :(得分:0)
这是我们部署的另一个解决方案。它涉及到猴子修补_add_installed_apps_translations
类的DjangoTranslation
方法的过程,以使项目应用程序的翻译优先于Django应用程序的翻译。
# patches.py
from __future__ import absolute_import, unicode_literals
import os
from django.apps import apps
from django.core.exceptions import AppRegistryNotReady
from django.utils.translation.trans_real import DjangoTranslation
def patchDjangoTranslation():
"""
Patch Django to prioritize the project's app translations over
its own. Fixes GitLab issue #734 for Django 1.11.
Might needs to be updated for future Django versions.
"""
def _add_installed_apps_translations_new(self):
"""Merges translations from each installed app."""
try:
# Django apps
app_configs = [
app for app in apps.get_app_configs() if app.name.startswith('django.')
]
# Non Django apps
app_configs = [
app for app in apps.get_app_configs() if not app.name.startswith('django.')
]
app_configs = reversed(app_configs)
except AppRegistryNotReady:
raise AppRegistryNotReady(
"The translation infrastructure cannot be initialized before the "
"apps registry is ready. Check that you don't make non-lazy "
"gettext calls at import time.")
for app_config in app_configs:
localedir = os.path.join(app_config.path, 'locale')
if os.path.exists(localedir):
translation = self._new_gnu_trans(localedir)
self.merge(translation)
DjangoTranslation._add_installed_apps_translations = _add_installed_apps_translations_new
然后在主应用程序的.ready()
方法中,调用patchDjangoTranslation
:
from .patches import patchDjangoTranslation
class CommonApp(MayanAppConfig):
app_namespace = 'common'
app_url = ''
has_rest_api = True
has_tests = True
name = 'mayan.apps.common'
verbose_name = _('Common')
def ready(self):
super(CommonApp, self).ready()
patchDjangoTranslation() # Apply patch
主要更改如下:
# Django apps
app_configs = [
app for app in apps.get_app_configs() if app.name.startswith('django.')
]
# Non Django apps
app_configs = [
app for app in apps.get_app_configs() if not app.name.startswith('django.')
]
app_configs = reversed(app_configs)
原始文件是:
app_configs = reversed(list(apps.get_app_configs()))
此块不是按INSTALLED_APPS
设置中出现的顺序来解释应用程序的翻译,而是输出将项目应用程序放置在Django应用程序之前的应用程序列表。由于仅在确定要使用的翻译时才会发生这种情况,因此它不会影响代码的任何其他部分,并且不需要其他更改。
它适用于Django 1.11到2.2。