Django实现国际化(多语言)设置步骤
Django使用了很久了,一直没怎么关注过多语言的问题(仅仅存在于知道有这个功能),刚好最近有项目要做多语言的站点,就对这方面着重看了一下。
话不多说,先看看最终的样式(我想一般的站点差不多也就是这样吧)

接下来在说具体的操作步骤是如何来实现的。
环境基础
python=3.8.5
django=3.1.5
理论来说貌似只要是django2及以上的貌似都可以用这套,这里好像没有什么很大的变更。
还有我用的mac, 这里遇到的问题,我后面也会说。
准备工作
创建html页面
{% load static %}
{% load i18n %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<form action="{% url 'set_language' %}" method="post">
{% csrf_token %}
<input type="hidden" name="next" value="{{ redirect_to }}">
<select name="language">
{% 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>
{% translate "language:" %} {{ LANGUAGE_CODE }}
<input type="submit" value="{% translate 'Switch' %}">
</form>
<h1>{% translate "这是标题" %}</h1>
<a href="#">{% translate "登陆" %}</a>
<a href="#">{% translate "登出" %}</a>
<p>{% translate "欢迎你!" %}</p>
</body>
</html>
这里需要注意的有下面几个
1、引入了{% load i18n %},也就是django的国际化支持;
2、在需要设置多语言的地方增加了{% translate %}标签,用来区分这里以后可能是需要设置多语言的;
3、在form表单中,使用get_current_language 获取当前的语言,使用``get_available_languages
获取可以使用的语言列表,然后遍历循环出语言的下拉选项框
数据库层面
如果需要对数据库内的内容进行展示,或者对admin里面的内容进行翻译,请在models.py中进行如下的操作,不过我这次的样例是没有用到的。
from django.db import models
from django.utils.translation import gettext_lazy as _
class MenuModel(models.Model):
# Translators:导航菜单
name = models.CharField(max_length=150,verbose_name=_('导航菜单名称'))
class Meta:
verbose_name = _('导航')
只需要引入from django.utils.translation import gettext_lazy as _ 然后给需要的字段前面增加即可。
路由设置
路由设置我使用的还是自带的i18n,所以相对比较简单。
# urls.py
from django.contrib import admin
from django.urls import path,include
from django.utils.translation import gettext_lazy as _
urlpatterns = [
...
path('admin/', admin.site.urls),
path('i18n/',include("django.conf.urls.i18n")),
]
settings.py设置
MIDDLEWARE = [
...
'django.middleware.locale.LocaleMiddleware', # 多语言中间件
....
]
from django.utils.translation import gettext_lazy as _
import os
# 语言包选项
LANGUAGES = [
('zh-hans',_('Chinese')),
('en',_('English')),
]
LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# 编译的语言文件存放路径,我这里是放在了根目录
LOCALE_PATHS = (
os.path.join(BASE_DIR,'locale'),
)
实操
完成了上面的这些操作,我们已经算是完成最基本的操作了,接下来首先需要我们去根目录记得创建locale文件夹,便于后续存放多语言文件。
执行django-admin makemessages -l zh_HANS -l en 要确保目录下一定要有 locale文件夹.这个命令是生成了2种语言的文件;
执行完毕后,应该就可以看到locale文件夹下已经有文件出现了。结构类似下面这样
- manage.py
- web
-...
- locale
- en/LC_MESSAGES
- django.mo
- zh_HANS/LC_MESSAGES
-django.mo
- ...
打开类似的目录,就可以看到下面这样
# 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 ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-04-13 22:13+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. Translators:导航菜单
#: my01/models/menu_models.py:9
msgid "导航菜单名称"
msgstr "Web Menu Name"
#: my01/models/menu_models.py:12
msgid "导航"
msgstr "Nav Bar"
#: my01/templates/index.html:12
msgid "这是标题"
msgstr "This is Title "
#: my01/templates/index.html:14
msgid "登陆"
msgstr "Login"
#: my01/templates/index.html:15
msgid "登出"
msgstr "Logout"
#: my01/templates/index.html:18
msgid "欢迎你!"
msgstr "Welcome!"
因为网站本身我们就是用中文的制作的,所以中文文件基本可以不用管,只要检查一下即可,着重检查一下英文的每个需要翻译的msgstrsh是否有翻译。
全部翻译完成后,继续执行命令django-admin compilemessages 编译二进制文件,执行完成后会发现在.mo文件的目录下会出现.po的二进制文件。
如果看到这些都已经全部生成,那么恭喜你,就已经全部搞定了,直接执行即可。
错误
这里就是我前面说为什么带上了我说我的系统问题。我在执行编译的时候,系统提示CommandError: Can't find msguniq. Make sure you have GNU gettext tools 0.15 or newer installed.
意思是说需要安装GUN gettext 0.15以上的版本。我还不太清楚在win下是否会出现这个问题。
mac解决就比较简单。我直接执行brew install gettext然后在执行就完美解决了。