Django翻译无法正常工作。

15

我正在尝试让Django的翻译系统工作,按照这里的教程进行操作。

这是我的两个视图(一个用于直接输出,一个用于模板),但都没有起作用。

def home(request):        
    output = _("hello") # (lazy)
    return HttpResponse(output)

def with_template(request):
    return render(request, 'translation_template.html')

这是第二个视图的模板文件:

{% extends "base_site.html" %}
{% load i18n %}

{% block content %}
<p>{% trans 'hello' %}</p>
{% language 'tr' %}
<p>{% trans 'hello' %}</p>
{% endlanguage %}
{% language 'tr-TR' %}
<p>{% trans 'hello' %}</p>
{% endlanguage %}
{% endblock %}

在我的设置文件中,我添加了以下内容:(如果需要,可以添加之前的部分)
LANGUAGE_CODE = 'en-us'    
# also tried LANGUAGE_CODE = 'tr'  and LANGUAGE_CODE = 'tr-TR'
PROJECT_DIR = os.path.dirname(__file__)

"""
# tried but didn't work
from django.conf.global_settings import TEMPLATE_CONTEXT_PROCESSORS
TEMPLATE_CONTEXT_PROCESSORS = (
    "django.contrib.context_processors.auth",
    "django.core.context_processors.i18n",
)
"""
LOCALE_PATHS = ( os.path.join(PROJECT_DIR, 'locale'), )
LANGUAGES = (
    ('tr', _('Turkish')),
    ('en', _('English')),
)

保存后,我在终端中执行了以下命令:

python ./manage.py makemessages -l tr

然后编辑新创建的myproject/locale/tr/LC_MESSAGES/django.po文件,使其包含以下内容:

msgid "hello"
msgstr "merhaba"

然后执行

python ./manage.py compilemessages

我重新启动了服务器。终端命令没有显示任何错误,但是当我加载视图时,没有一个“hello”被翻译。

我在这里做错了什么?

感谢任何帮助!

编辑:

我在en/../django.po中发现了可疑的代码,可能与此无关,但也许是。这是文件的开头。模糊(empty->empty)翻译,可能是问题吗?

# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""

少于1分钟内得分为负数。为什么? - jeff
2
你确定你的浏览器正在请求土耳其页面吗?尝试在你的模板中打印出当前语言以进行调试:{% get_language_info for LANGUAGE_CODE as current_lang %}{{ current_lang.code }} - Selcuk
@Anzel 是的。@Selcuk它显示为“en”。我还添加了一个英语翻译,“eng_hello”,但它不适用。 - jeff
你的.po文件中是否有以"fuzzy"开头的行?如果是,将它们删除。 - Selcuk
不,它们不是模糊的。我的 {% language 'tr' %} 试用版难道不应该为我做这个吗? 编辑:我将 Chrome 的设置更改为土耳其语,@Selcuk 的代码这次显示 tr,但仍然没有翻译... - jeff
显示剩余2条评论
11个回答

28

我解决了我的问题。在我的情况下,问题出在settings.py文件中LOCALE_PATHS的定义上。

我通过在视图中进行测试解决了这个问题:

from TranslationTest import settings
return HttpResponse(settings.LOCALE_PATHS)

它显示的是home/myProjects/TranslationTest/TranslationTest/locale,但是makemessageshome/myProjects/TranslationTest/locale中生成文件。

所以我按照以下方式更改了我的设置:

SITE_ROOT = os.path.dirname(os.path.realpath(__name__))
LOCALE_PATHS = ( os.path.join(SITE_ROOT, 'locale'), )

现在它可以工作了。

但我仍然想知道,为什么makemessages没有理解应该创建在settings.py指定的LOCALE_PATHS中的文件?

据我了解,它总是在SITE_ROOT/locale中生成本地化文件,所以我们应该始终将LOCALE_PATHS设置为此目录?如果这是默认值,为什么要设置它呢?我希望能获得更多关于这个问题的信息。

感谢所有的帮助!


1
打印出 settings.LOCALE_PATHS 确实帮助我解决了这个问题。LOCALE_PATHS 应该包括项目中所有的 'locale' 文件夹。谢谢。 - Homer Wang

9

如果您启用了本地化中间件,将会出现这种情况。这样做的话,我认为您的会话语言环境取决于您的浏览器语言环境。

如果您注释掉本地化中间件,应该能按预期工作。

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    #'django.middleware.locale.LocaleMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

7
请牢记,如果您的语言中包含一个国家名称,例如fa-IR,在您的设置文件中您必须添加以下内容:
LANGUAGE_CODE = 'fa-IR'

但是当你想要调用makemessages命令时,你需要将-更改为_

makemessages -l fa_IR

关于此,来自文档在所有情况下,期望翻译文件所在的目录名使用语言环境名称表示。例如:de、pt_BR、es_AR等。 - jmq

6

我尝试了以上几种解决方案,但都没有成功。后来我意识到,在运行 makemessages 命令之后,我忘记运行 compilemessages 命令了。所以请确保您运行了以下命令:

python manage.py compilemessages 

运行makemessages之后,compilemessages命令将会把你的本地目录下的.po文件转换成.mo文件。这是必要的,因为.mo文件是gettext能够理解的唯一文件类型。没有.mo文件,翻译就无法生效,这也是我遇到的情况。请注意保留HTML标签。

2
截至今天,即使使用Django 3.2版本,这个问题仍然存在。 在我的情况下,我的设置如下:
C:.
├───documents
├───project
│   ├───apps
│   │   ├───accounts
│   │   │   ├───...
│   │   ├───common
│   │   │   ├───...
│   │   └───...
│   ├───locale
│   │   └───it
│   │       └───LC_MESSAGES
│   └───...
└───tests

设置文件是这样设置的:

LANGUAGE_CODE = 'it'

LOCALE_PATHS = [
    os.path.join(Path(__file__).resolve().parent, "locale"),
]

LANGUAGES = [
   ('en', _('English')),
   ('it', _('Italian')),
]

关键在于LOCALE_PATHS的定义。Django-admin在某种程度上与Django环境不同步。

谢谢!我之前翻译的内容一直没有显示,但是这个locale_path完美解决了问题! - Sebastian Latorre

1
我想提醒一下一个让我遇到小问题的事情,那就是我应该更改浏览器的语言(从选项中)。然而,我做了所有的事情,但我无法看到翻译后的文本。顺便说一下,我不想使用任何特定的URL来查看翻译。

0

你可能需要阅读Django如何发现语言偏好

太长不看:

语言中间件按以下顺序决定用户语言:

  1. 在根URLconf中使用i18n_patterns函数
  2. 如果没有,则查找由LANGUAGE_COOKIE_NAME设置设定的cookie
  3. 如果还是找不到,它会查看浏览器发送的Accept-Language HTTP头
  4. 最后,它使用全局LANGUAGE_CODE设置

在我的案例中,我遵循了一个教程,但是我不知道为什么我的语言没有改变。

我已经完成了包含两种语言翻译字符串的本地化文件夹,并且已经正确设置了LOCALE_PATH和其他设置。

因此,为了测试,我将LANGUAGE_CODE更改为用印地语显示文本,但我不知道语言的优先级。

在我的设置中,我设置了以下内容:

LANGUAGES = (
    ('hi', _('Hindi')),
    ('en', _('English')),
)
LANGUAGE_CODE = 'hi'

发生的情况是我没有指定语言的 cookie,所以优先级落在浏览器默认语言上,该语言通过 http 标头传递。

因此,它从未到达我的设置中的 LANGUAGE_CODE,而请求中的 request.LANGUAGE_CODE 语言设置为 en。

为了解决这个问题,我将 cookie 设置为优先于浏览器。

from django.conf import settings
from django.http import HttpResponse
from django.utils import translation
user_language = 'hi'
translation.activate(user_language)
response = HttpResponse(...)
response.set_cookie(settings.LANGUAGE_COOKIE_NAME, user_language)

我从这里拿来的明确设置活动语言


0
你需要将JavaScript代码放在静态文件夹内的一个文件中(你需要运行collectstatic命令),以便生成djangojs.po文件。因为Django默认会在处理JS文件时查找这个目标位置。

0

你可以尝试使用Candy Translate代替Django原生的翻译模块。它更容易使用,不需要设置中间件,基本上为您完成了大部分工作。

它还允许您在Excel文件中管理翻译,这在将文本发送给翻译人员时非常方便。

它有一些限制,但对于我所有的网站来说,它已经足够,并且实现速度更快。


0

将本地中间件添加到Django中间件对我很有帮助 'django.middleware.locale.LocaleMiddleware',


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