Django - 如何使翻译生效?

38

我正在尝试使用i18n以不同的语言渲染模板。我已经阅读了所有相关的内容,包括设置语言代码、创建和编译翻译文件、在模板中包含翻译标签等等,但我的模板仍然以英语呈现,即使{{ LANGUAGE_CODE }}变量指向我想要呈现的正确(且不同)的代码。我错过了什么?

模板:

{% extends "base.html" %}
{% load i18n %}
{% get_current_language as LANGUAGE_CODE %}
{% get_available_languages as LANGUAGES %}
{% get_current_language_bidi as LANGUAGE_BIDI %}
{% block title %}{% trans "translation test" %}{% endblock %}
{% block content %}
<div id="some-text">
  {% trans "some translated text goes here" %}
  {% blocktrans %}
  <ol>
    <li>here are some</li>
    <li>items that should be</li>
    <li>translated as well</li>
  </ol>
  {% endblocktrans %}
  <ul>
      <li>The current language is <b>{{ LANGUAGE_CODE }}</b></li>
      {% if LANGUAGE_BIDI %}
        <li>The current language is bidirectional</li>
      {% else %}
        <li>The current language is <b>not</b> bidirectional</li>
      {% endif %}
      <li>Available languages are:
        <ul>
        {% for lang in LANGUAGES %}
          <li>{{ lang.1}}</li>
        {% endfor %}
        </ul>
      </li>
  </ul>
</div>
{% endblock %}

视图:

from django.shortcuts import render_to_response
from django.template import RequestContext
from pdb import set_trace as debugger
def check(request):
    return render_to_response('index.html', context_instance=RequestContext(request)

命令行(我已在.po文件中填写了正确的翻译):

$ django-admin.py makemessages -l he-il -e html
$ django-admin.py compilemessages

settings.py:

# Language code for this installation. All choices can be found here:
# http://www.i18nguy.com/unicode/language-identifiers.html
LANGUAGE_CODE = 'he-il'

gettext = lambda s: s
LANGUAGES = (
    ('he-il', gettext('Hebrew')),
    ('en-us', gettext('English')),
)

# If you set this to False, Django will make some optimizations so as not
# to load the internationalization machinery.
USE_I18N = True

TEMPLATE_CONTEXT_PROCESSORS = (
    "django.core.context_processors.auth",
    "django.core.context_processors.i18n",
)

MIDDLEWARE_CLASSES = (
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.locale.LocaleMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
)
9个回答

71

只需像以下示例一样将生成的区域设置文件路径添加到settings.py文件中:

LOCALE_PATHS = ( "/xxx/xxx/Projects/xxx/sites/avb/locale/",)

9
多年后你的回答依然有用!谢谢! - Daviddd
4
另外,我建议使用 os.path.join(BASE_DIR, 'locale')。不要使用相对路径,因为虽然在开发环境中可以工作,但根据服务器等情况,在实际运行中可能无法正常工作。 - Wtower

28

这是一个完整的解决方案,我从Django 1.4开始使用,一直到1.7.1:

在settings.py中...

将locale添加到MIDDLEWEAR_CLASSES中,它可以根据请求启用语言选择:

'django.middleware.locale.LocaleMiddleware',

添加 LOCALE_PATHS,这是您的翻译文件存储的位置:

LOCALE_PATHS = (
    os.path.join(PROJECT_PATH, 'locale/'),
)

启用I18N:

USE_I18N = True    

设置您将要将网站翻译成的语言:

ugettext = lambda s: s
LANGUAGES = (
    ('en', ugettext('English')),
    ('fr', ugettext('French')),
    ('pl', ugettext('Polish')),
)

将i18n模板上下文处理器添加到TEMPLATE_CONTEXT_PROCESSORS中,请求现在将包括LANGUAGES和LANGUAGE_CODE:

'django.core.context_processors.i18n',

在 urls.py 文件中:
在 url_patterns 中添加以下内容,它将启用设置语言重定向视图:
url(r'^i18n/', include('django.conf.urls.i18n')),

有关此内容的更多信息,请参见翻译中的杂项。

添加以下导入,并使用i18n_patterns封装要翻译的URL。这是我的样子:

from django.conf.urls.i18n import i18n_patterns
from django.utils.translation import ugettext_lazy as _

urlpatterns = patterns('',
    url(r'^admin/', include(admin.site.urls)),
    url(r'^i18n/', include('django.conf.urls.i18n')),
)

urlpatterns += i18n_patterns('',
    (_(r'^dual-lang/'), include('duallang.urls')),
    (r'^', include('home.urls')),
)

现在,无论您在哪里使用文本并希望进行转换,都可以导入lazytext并像这样将每个字符串包装起来:_('text'),您甚至可以转到其他urls.py文件并进行url翻译,如下所示:

url(_(r'^dual_language/$'), landing, name='duallang_landing'),

您可以在其他文件中(例如models.py、views.py等)包装要翻译的文本。以下是一个示例模型字段,其中包含标签和帮助文本的翻译:

name = models.CharField(_('name'), max_length=255, unique=True, help_text=_("Name of the FAQ Topic"))

在您的HTML模板中...

对于您的模板也要这样做,并加载i18n模板标签,使用trans和transblock翻译您想要翻译的静态内容。以下是一个例子:

{% load i18n %}

{% trans "This is a translation" %}<br><br>
{% blocktrans with book_t='book title'|title author_t='an author'|title %}
This is {{ book_t }} by {{ author_t }}. Block trans is powerful!
{% endblocktrans %}

现在为每个区域设置运行makemessages:

./manage.py makemessages -l pl

现在只需要进入您的/locales文件夹,并编辑每个.po文件。为每个msgstr填写数据。以下是一个这样的例子:
msgid "English"
msgstr "Angielski"

最后编译消息:

./manage.py compilemessages

如果要对模型实例数据进行翻译,您可以使用一些可重复使用的软件包,例如:

关于翻译还有很多需要学习的地方,internationalization 和这个主题密切相关,因此也请查看相关文档。我还建议您检查一些可用于 Django 的国际化软件包,例如 django-rosettadjango-linguo。它们帮助翻译模型内容,django-rosetta 不会在数据库中为此创建新条目,而 django-linguo 则会。

如果您按照这些步骤操作,应该可以良好启动。我相信这是将您的站点运行在多种语言环境下的最标准方法。干杯!


谢谢您的反馈 :) 请注意,您必须将LocalMidleware放在正确的位置:它应在SessionMiddleware之后,因为LocaleMiddleware使用会话数据。并且它应该在CommonMiddleware之前,因为CommonMiddleware需要激活语言来解析所请求的URL。更多信息可以在这里找到。 - WhiteDragon

20
我可能错了-因为我唯一使用翻译工具的时间是很久以前的一个测试项目,但我认为您不想要这个:$ django-admin.py makemessages -l he-il -e html。而是这个:$ django-admin.py makemessages -l he_il -e html。请注意he_il中的下划线。
我也遇到了pt-BR的问题,直到我使用pt_br制作了消息文件,然后事情开始正常运转...是的,这并不明显,我找不到任何关于它的文档。希望这可以帮到您。

2
刚刚遇到了一个有趣的问题。LANGUAGE设置应该使用破折号,但/ locale /中的路径应该使用下划线。 - Andrew
1
+1 这就是它!网络上有很多关于这个问题的疑问,而你已经解决了它。我只是将我的语言从fr-fr重命名为fr_fr,然后一切都恢复正常了!(在Django重新启动后)。 - mkoistinen
对我来说,我必须使用:LANGUAGE_CODE = 'en_GB',而在 LANGUAGES = (('en-gb', ugettext('English')), ...) 中。 - dalore

15

我有同样的问题。但是我通过在.po文件中添加“Language:”来解决它。在我的情况下,.po文件不包含“Language:”属性,看起来像...

"Language-Team: LANGUAGE \n"
"Language: \n"
"MIME-Version: 1.0\n"

但是当我添加语言代码(在我的情况下为'ru'或'en')时

"Language-Team: LANGUAGE \n"
"Language: ru\n"
"MIME-Version: 1.0\n"

对我起作用了。


5

我遇到了相同的问题,看起来你的区域设置路径必须以斜杠结尾

LOCALE_PATHS = (
    '/dir/to/my/locale/', 
)

3
谢谢。以下是需要翻译的内容:“Thank you. This were my case. Here's a snippet for those running the same problem: LOCALE_PATHS = os.path.join(BASE_DIR, '<app-name>','locale/')”。翻译如下:谢谢。这是我的情况。对于那些遇到相同问题的人,以下是一个片段:LOCALE_PATHS = os.path.join(BASE_DIR, '<应用程序名称>', 'locale/') - Thales Ceolin
1
在我的情况下,我也缺少了尾随逗号“,”。 - Jorge Alfaro

2
是的,你需要像celopes建议的那样制作消息文件,然后进行编译。
python manage.py compilemessages

但是你仍然会遇到一个问题。
暂时禁用LocaleMiddleware,也就是移除这个。
django.middleware.locale.LocaleMiddleware

如果您不需要在运行时切换语言,则不要从中间件列表中选择它,但如果确实需要,则有一个解决方案。我之前也遇到过同样的问题,有人向我解释了这个问题。

另外,我之前也遇到过这个奇怪的问题。在.py文件中使用反斜杠包装的字符串会使Makemessages命令失败。


1
Django 的翻译文档很好,但是比较冗长,不幸的是你需要阅读大部分内容。 - Evgeny
我移除了那个中间件,但是没有任何变化。页面仍然只显示英文,尽管LANGUAGE_CODE指向'he'(我将其从'he-il'更改,因为这是django.conf.locale的设置)。有什么想法吗? - sa125
在消息构建和编译过程中是否出现任何错误信息?请查看 locale/he/django.po 文件,是否有 #、fuzzy 标记? - Evgeny
你有 locale/he/django.mo 文件吗? - Evgeny
添加了指向另一个可能问题的链接。 - Evgeny
我还记得“错误的字符串包装”的症状是django.po文件非常不完整,因此大多数消息都无法翻译。 - Evgeny

2
我实现这个方法的方式是使用 django 在其自己的翻译文件中使用的确切语言代码(而不是使用 settings.py 中提供的链接),假设此语言受支持(如果不是,则会变得复杂,因为您还必须向 django 提供自己的翻译文件)。
我通过进入 $DJANGO_DIR/conf/locale 并查看目录名称(对我来说在 /usr/local/lib/python2.6/dist-packages/django/conf/locale,但根据操作系统等原因可能会有所不同)找到了这个代码。

1

我曾经遇到过同样的问题,尝试切换语言,但 Django 没有响应。没有错误,也没有警告,但 Django 将语言切换为 pl-pl(在我的情况下)。然而,删除 locale 中的所有文件夹并执行命令:django-admin.py makemessages -l pl_PL(使用下划线而不是破折号,并将第二个 PL 大写),解决了这个问题。

希望能对一些人有所帮助。


0

我曾经遇到过同样的问题。我在另一个类似问题下的这个链接中详细解释了它。

简而言之,我的问题已通过重新加载此代码的服务器得到解决:

sudo /etc/init.d/uwsgi reload

现在,每次我更改短语并编译语言文件后,我也会重新加载服务器以查看更改。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接