跳转到内容

Django国际化

来自代码酷

Django国际化[编辑 | 编辑源代码]

介绍[编辑 | 编辑源代码]

Django国际化(Internationalization,简称i18n)是指将Django应用程序适配为支持多种语言和区域设置的过程。这一功能使得开发者能够为全球用户提供本地化的内容,包括翻译文本、日期/时间格式、数字格式等。Django通过内置的翻译系统(translation system)简化了这一过程。

国际化通常涉及三个主要方面:

  • 文本翻译:将界面中的字符串转换为目标语言。
  • 本地化格式:根据地区调整日期、时间、数字的显示方式。
  • 时区处理:正确处理用户所在时区的时间显示。

基本配置[编辑 | 编辑源代码]

在Django项目中启用国际化功能,需在settings.py中进行以下配置:

# settings.py

# 启用国际化
USE_I18N = True

# 启用本地化格式(如日期、数字)
USE_L10N = True

# 设置支持的语言
LANGUAGES = [
    ('en', 'English'),
    ('zh-hans', '简体中文'),
    ('es', 'Spanish'),
]

# 设置默认语言
LANGUAGE_CODE = 'en'

# 指定翻译文件所在目录
LOCALE_PATHS = [
    os.path.join(BASE_DIR, 'locale'),
]

中间件配置[编辑 | 编辑源代码]

Django的LocaleMiddleware负责根据用户请求确定语言偏好。需将其添加到MIDDLEWARE中:

MIDDLEWARE = [
    ...
    'django.middleware.locale.LocaleMiddleware',
    ...
]

标记可翻译文本[编辑 | 编辑源代码]

在Django模板和Python代码中,需使用特定的函数标记需要翻译的文本。

在模板中[编辑 | 编辑源代码]

在模板中,使用{% trans %}标签或{% blocktrans %}块标记可翻译内容:

<!-- 简单文本翻译 -->
{% load i18n %}
<h1>{% trans "Welcome to our website!" %}</h1>

<!-- 带变量的翻译 -->
<p>{% blocktrans with username=user.username %}Hello, {{ username }}!{% endblocktrans %}</p>

在Python代码中[编辑 | 编辑源代码]

在视图或其他Python代码中,使用gettext()(通常别名为_())函数:

from django.utils.translation import gettext as _

def my_view(request):
    output = _("Welcome to our site!")
    return HttpResponse(output)

提取翻译字符串[编辑 | 编辑源代码]

Django提供了makemessages命令来提取所有标记为可翻译的字符串到.po文件中:

# 提取所有语言
django-admin makemessages -l zh_Hans
django-admin makemessages -l es

# 更新已有翻译
django-admin makemessages -a

生成的.po文件位于locale/目录下,结构如下:

graph TD locale/ ├── zh_Hans/ │ └── LC_MESSAGES/ │ ├── django.po │ └── django.mo └── es/ └── LC_MESSAGES/ ├── django.po └── django.mo

编译翻译文件[编辑 | 编辑源代码]

翻译完成后,需将.po文件编译为二进制.mo文件:

django-admin compilemessages

语言切换[编辑 | 编辑源代码]

Django提供了多种方式让用户切换语言:

URL前缀[编辑 | 编辑源代码]

urls.py中配置:

from django.conf.urls.i18n import i18n_patterns

urlpatterns = i18n_patterns(
    path('', views.home, name='home'),
    prefix_default_language=False,
)

这样URL会变为/en//zh-hans/等形式。

通过视图切换[编辑 | 编辑源代码]

可以创建一个语言切换视图:

from django.http import HttpResponseRedirect
from django.utils.translation import activate

def set_language(request, language_code):
    activate(language_code)
    request.session[settings.LANGUAGE_SESSION_KEY] = language_code
    return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/'))

高级主题[编辑 | 编辑源代码]

复数形式[编辑 | 编辑源代码]

Django支持处理不同复数形式的翻译:

from django.utils.translation import ngettext

count = 5
message = ngettext(
    'There is %(count)d apple.',
    'There are %(count)d apples.',
    count
) % {'count': count}

本地化格式[编辑 | 编辑源代码]

Django会自动根据当前语言环境格式化日期、数字等:

{% load l10n %}

<!-- 本地化日期 -->
{{ value|date }}

<!-- 本地化数字 -->
{{ value|floatformat }}

JavaScript国际化[编辑 | 编辑源代码]

对于前端内容,Django提供了JavaScript翻译功能:

1. 首先在视图中包含JavaScript翻译目录:

from django.views.i18n import JavaScriptCatalog

urlpatterns = [
    path('jsi18n/', JavaScriptCatalog.as_view(), name='javascript-catalog'),
]

2. 在模板中引入:

<script src="{% url 'javascript-catalog' %}"></script>

3. 在JavaScript中使用:

const translated = gettext('This text will be translated');

实际案例[编辑 | 编辑源代码]

假设我们有一个多语言博客系统:

1. 在models.py中定义可翻译字段:

from django.db import models
from django.utils.translation import gettext_lazy as _

class BlogPost(models.Model):
    title = models.CharField(_('Title'), max_length=200)
    content = models.TextField(_('Content'))
    created_at = models.DateTimeField(_('Created at'), auto_now_add=True)

2. 在模板中显示本地化内容:

{% load i18n l10n %}

<article>
    <h1>{{ post.title }}</h1>
    <div class="content">{{ post.content }}</div>
    <time datetime="{{ post.created_at|date:'c' }}">
        {% blocktrans with created_date=post.created_at|date %}Posted on {{ created_date }}{% endblocktrans %}
    </time>
</article>

<div class="language-switcher">
    <form action="{% url 'set_language' %}" method="post">
        {% csrf_token %}
        <select name="language">
            {% get_current_language as LANGUAGE_CODE %}
            {% get_available_languages as LANGUAGES %}
            {% for code, name in LANGUAGES %}
                <option value="{{ code }}" {% if code == LANGUAGE_CODE %}selected{% endif %}>
                    {{ name }}
                </option>
            {% endfor %}
        </select>
        <input type="submit" value="{% trans 'Switch' %}">
    </form>
</div>

最佳实践[编辑 | 编辑源代码]

1. 尽早规划国际化:在项目初期就考虑国际化需求 2. 保持字符串简洁:避免长而复杂的句子,便于翻译 3. 避免拼接字符串:如"Hello " + name + "!"应改为_("Hello %(name)s!") % {'name': name} 4. 测试所有语言:确保界面在不同语言下都能正常显示 5. 考虑RTL语言:如阿拉伯语、希伯来语等从右向左书写的语言

常见问题[编辑 | 编辑源代码]

Q: 为什么我的翻译没有生效? A: 请检查: 1. 是否正确标记了可翻译字符串 2. 是否运行了makemessagescompilemessages 3. 翻译文件是否放在正确的locale目录 4. 浏览器是否发送了正确的Accept-Language

Q: 如何处理动态内容翻译? A: 对于用户生成内容,可以考虑: 1. 为每种语言保存不同版本的文本 2. 使用机器翻译API(如Google Translate) 3. 让用户自己提交不同语言的版本

总结[编辑 | 编辑源代码]

Django国际化是一个强大的功能,允许开发者轻松创建多语言网站。通过合理使用翻译系统、本地化格式和语言切换功能,可以为全球用户提供更好的体验。虽然初始设置需要一些工作,但Django的工具链使得整个过程相对简单高效。