django的i18n国际化和l10n本地化翻译

settings.py 设置

from django.utils.translation import gettext_lazy as _

#添加middleware至对应位置
MIDDLEWARE = [
#...
'django.middleware.locale.LocaleMiddleware',
]

#添加locale目录,用于存放翻译文件(*.po,*.mo)
LOCALE_PATHS = [
    os.path.join(BASE_DIR, 'locale'),
]

#添加语言
LANGUAGES = [
  ('zh-hans', _('Chinese')),
  ('en', _('English')),
]

注意:这里是中划线 zh-hans

urls.py 设置

from django.conf.urls.i18n import i18n_patterns

urlpatterns = [
    path('i18n/', include('django.conf.urls.i18n')),
    #sitemap.xml... 
    path('sitemap.xml', sitemap, {'sitemaps': sitemaps},
         name='django.contrib.sitemaps.views.sitemap'),
]

urlpatterns += i18n_patterns(
    path('admin/', admin.site.urls),
    #...
)

注意:i18n_patterns后面没有中括号[]!并且i18n_patterns只能用在项目配置,不能放到app的urls.py里面。如何添加sitemap请参考:django如何快速生成基本的静态sitemap

模板template 设置

小技巧:动态修改html的语言属性

{% load i18n %}
{% get_current_language as LANGUAGE_CODE %}
<html lang="{{ LANGUAGE_CODE }}">

小技巧:动态修改title的语言

{% trans "Welcome" as the_title %}
<title>{{ the_title }}</title>
<meta name="description" content="{{ the_title }}">
或者直接
{% trans "title" %}

小技巧:翻译语言块

{% blocktrans %}
hello
{% endblocktrans %}

注意: {% load i18n %} 必须要

生成语言编辑文件po

python manage.py makemessages -l zh_Hans

注意:是下划线,并且H大写,这是个大坑,如果写成小写,会不生效。

po文件如何编辑

ubuntu下安装poedit,非常方便。windows下可以查找相关工具。

sudo apt install poedit

poedit

编译po文件,生成mo

python manage.py compilemessages

添加切换语言选项框(bootstrap版,可以自行定制)

<div class="text-center">
    <form action="{% url 'set_language' %}" method="post">
    {% csrf_token %}
    <div class="input-group">
    <input name="next" type="hidden" value="{{ redirect_to }}">
        <select name="language" class="form-control">
            {% get_current_language as LANGUAGE_CODE %}
            {% get_available_languages as LANGUAGES %}
            {% get_language_info_list for LANGUAGES as languages %}
            {% for language in languages %}
                <option value="{{ language.code }}"{% if language.code == LANGUAGE_CODE %} selected{% endif %}>
                    {{ language.name_local }} ({{ language.code }})
                </option>
            {% endfor %}
        </select>
      <div class="input-group-append">
        <button class="btn btn-info" type="submit">Go</button>
      </div>
    </div>

    </form>
</div>