Django 翻译不起作用

Django translations does not work

我正在尝试让 Django 的翻译系统工作,遵循教程 here

这是我的两个视图(一个是直接输出,一个是模板),都不行。

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" 中的 none 被翻译了。

我做错了什么?

感谢您的帮助!

编辑:

我在 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 ""

我解决了我的问题。就我而言,问题出在 settings.py.

中的 LOCALE_PATHS 定义

我在视图中测试了它:

from TranslationTest import settings
return HttpResponse(settings.LOCALE_PATHS)

它正在显示 home/myProjects/TranslationTest/TranslationTest/locale,但是 makemessages 正在生成 home/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 设置为此?如果这是默认值,为什么要设置它呢?如果能提供有关此问题的更多信息,我将不胜感激。

感谢大家的帮助!

我只是想提醒一些导致我的小问题,那就是我应该更改浏览器的语言(从选项)。 但是我完全做了所有的事情,但是我看不到翻译的文本。 顺便说一句,我不想​​使用任何特定的 url 来查看翻译。

如果您激活了语言环境中间件,就会发生这种情况。通过这样做,我认为您的本地会话取决于您的浏览器区域设置。

如果您评论语言环境中间件,它应该会按预期工作。

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',
]

并记住您的语言中是否包含国家/地区,例如fa-IR,在你的设置文件中你必须添加:

LANGUAGE_CODE = 'fa-IR'

但是当你想调用 makemessages 命令时,你应该将 - 更改为 _:

makemessages -l fa_IR

对我来说在线评论没问题

USE_I18N = True
USE_L10N = True
LANGUAGE_CODE = 'uk'
LANGUAGES = (
('uk', _('Ukrainian')),
# ('en', _('English')),
)

项目根目录中没有语言环境文件夹,没有自定义 LOCALE_PATHS

将本地中间件添加到 django 中间件对我有用 'django.middleware.locale.LocaleMiddleware',

您可能需要阅读这篇文章 How Django discovers language preference

TLDR;

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

  1. i18n_patterns 根目录中的函数 URLconf
  2. 否则,它会查找由 LANGUAGE_COOKIE_NAME 设置
  3. 设置的 cookie
  4. 否则,它会查看您的 浏览器
  5. 发送的 Accept-Language HTTP header
  6. 否则,它使用全局 LANGUAGE_CODE 设置

就我而言,我遵循了一个教程,但我不知道为什么我的语言没有改变。

我已经完成了语言环境文件夹,我已经在其中翻译了两种语言的所有字符串,并且我已经正确设置了 LOCALE_PATH 和其他内容。

所以为了测试,我更改了 LANGUAGE_CODE 以用印地语显示文本,但我不知道语言优先级的东西。

我在设置中设置了以下内容

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

所以发生的事情是我没有指定语言的 cookie,因此优先级落在 http header 中传递的浏览器默认语言 header。

所以它从来没有出现在我的设置中的 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)

这是我从这里拿来的 Explicitly setting the active language

截至今天,对于 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 环境不同步。

我几乎尝试了上面提供的所有解决方案,但都没有成功。然后我意识到我忘记了 运行 compilemessagesmakemessages 命令之后。所以确保你 运行:

python manage.py compilemessages 

运行宁发消息后。 compilemessages 命令的作用是将 .po 文件转换为本地目录中的 .mo 文件。这是必需的,因为 .mo 文件是 gettext 唯一可以理解的文件。没有 .mo 文件翻译将无法工作,我就是这种情况。