【Django】如何设置支持多语种网站,中文/英文网站

首先,需要明确一点:我们要实现的中英对照翻译,这个翻译不是浏览器翻译的,也不是Django帮你翻译。这个需要你自己事先手动翻译好,存放在专门翻译文件中,Django只是事后调用而已。

第一步 新建项目后,修改settings.py

假如创建的项目叫xiangmu,创建的app叫wangzhan, 然后在xiangmu目录下新建locale文件夹,用于保存翻译消息文件(.po和.mo格式的文件)。修改配置文件settings.py:

# 引入模块
from django.utils.translation import ugettext_lazy as _

# 引入app
INSTALLED_APPS = [
    ...
    'wangzhan',
]

# 引入语言中间件,(注意位置,不要变)
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.locale.LocaleMiddleware',  # 语言插件
    'django.middleware.common.CommonMiddleware',
    ...
]

# 默认语言为英文
LANGUAGE_CODE = 'en-us'

# 设置I18n和L10N为True
USE_I18N = True
USE_L10N = True 

# 指定支持语言。这里为了简化只支持简体中文和英文
LANGUAGES = (
    ('en', _('English')),
    ('zh-hans', _('Simplified Chinese')),
)

# 用于存放django.po和django.mo编译过的翻译文件
PROJECT_ROOT = os.path.dirname(os.path.realpath(__name__))
LOCALE_PATHS = (
    os.path.join(PROJECT_ROOT, 'locale'),
)

特别说明:
1、使用ugettext_lazy这个方法的作用是在.py文件文件中标记需要翻译的字符串,对其进行惰性参照存储,而不是对字符串进行真正的翻译。

2,、在models.py和views.py文件中,定义字段时,会用到ugettext_lazy,来指定标记需要翻译的字符串。

3、在模板html文件中,并不能直接使用ugettext_lazy这个方法,而是使用

# 开头先要引入i18n
{
   % load i18n %}

# 该标签标记定义需要翻译的字符“string”
{
   % trans "string" %}

# 该标签标记定义需要翻译的变量
{
   % blocktrans%} {
   %endblocktrans %}

小知识:

  • 这两个标签也不是对字符串进行真正的翻译,只是标记而已。
  • i18n是国际化(Internationalization)的缩写。i 和 n 之间有 18 个字母,简称 I18N。
  • l10n是本地化(localization)的缩写。l 和 n 之间有 10 个字母,简称 L10N。

第二步 修改项目的urls.py, 增加国际化i18n的支持

这里的urls.py是项目下的,而不是app下urls.py)。
i18n_patterns的作用:让每个url前面自动加上所选语言的代码,比如/en/, /zh-hans/ 等

# 项目下的urls.py

from django.contrib import admin
from django.urls import path, include
from django.conf.urls.i18n import i18n_patterns

urlpatterns = [
    path('i18n/', include('django.conf.urls.i18n')),
]

urlpatterns += i18n_patterns(
    path('admin/', admin.site.urls),
    path('', include('wangzhan.urls')),
)
# app(wangzhan)下的urls.py

from django.contrib import admin
from django.urls import path
from . import views

app_name = 'wangzhan'
urlpatterns = [
    path('', views.index, name='index'),
]

此时,可以通过访问Django自带的admin,来检验语言国际化设置是否成功:
分别访问http://127.0.0.1:8000/en/admin/http://127.0.0.1:8000/zh-hans/admin/

第三步 修改视图文件views.py

在视图中我们使用ugettext_lazy方法标记了一个需要翻译的字符串"Welcome to China"。

from django.shortcuts import render
# 进入ugettext_lazy方法
from django.utils.translation import ugettext_lazy as _

# Create your views here.
def index(request):
    context = {
   'msg': _("Welcome to China")}   # 定义要翻译的字符
    return render(request, 'wangzhan/index.html', context)

第四步 在index.html调用标签

<!DOCTYPE html>
{
   % load static %}
{
   % load i18n %}
<html lang="en">
<head>
...
...
...


# 用于语言的选择切换 (必须是POST请求)
<form class="form-inline ml-3-md" action="{% url 'set_language' %}" method="post">   # 变量set_language = /i18n/setlang/

               {
   % 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 }}
 </option>

                        {
   % endfor %}
 </select>
 <div class="input-group-append">
 <button type="submit" class="btn btn-inline btn-sm bg-warning">
                        {
   % trans "Select" %}
 </button>
 </div>
 </div>
 </form>
...
...
...

# 
{
   % block content %}
<div class="py-4 px-3 bg-light">
 <div class="container">
         {
   % get_current_language as LANGUAGE_CODE %}
 <h4>{
   % trans 'Current language code' %}: {
   {
    LANGUAGE_CODE }}</h4>
 <p><small>{
   % trans "Welcome to our page" %}</small></p>
 <hr/>
 <p>{
   % blocktrans %} {
   {
    msg }} {
   % endblocktrans %}</p>
 </div>
</div>
{
   % endblock %}

  • {% load i18n %}以后,你可以使用get_current_language标签获得当前语言。
  • 模板中使用{% trans “string” %},string是需要翻译的文本。
  • {% blocktrans%} {%endblocktrans %}标签来标记了两个需要翻译的字符串,
    一个是模板中已存在的,一个是视图函数传递过来的变量。

更多用法:

#普通用法
{% blocktrans %}This string will have {
  { value }} inside.{% endblocktrans %}

#增加过滤器
{% blocktrans with amount=article.price %}
That will cost $ {
  { amount }}.
{% endblocktrans %}
{% blocktrans with myvar=value|filter %}
This will have {
  { myvar }} inside.
{% endblocktrans %}

#多个过滤器
{% blocktrans with book_t=book|title author_t=author|title %}
This is {
  { book_t }} by {
  { author_t }}
{% endblocktrans %}

#注意:其他bolck tags (例如 {% for %} or {% if %}) 不允许在 blocktrans tag内部.

此时,启动测试服务器,应该能看到页面已经能正确显示。但是当你切换不同语言时,页面显示的内容还是一样的,这是因为我们还没对那些字符串进行翻译啊

第五步 生成.po和.mo编译消息文件

1、在\xiangmu\locale\zh_HANS\LC_MESSAGES目录下,生成.po文件
# django-admin makemessages -l 语言简写
django-admin makemessages -l zh_Hans    # 简体中文
django-admin makemessages -l zh_Hant    # 繁体中文
django-admin makemessages -l ko-kr      # 韩文
django-admin makemessages -l ja         # 日文 
# 等等(以此类推....)

在这里插入图片描述

注意:
在JavaScript多语言这里遇到个坑,js的翻译不管是中文还是英文,都是显示英文翻译。原因是编译的时候,应该用 zh_Hans 而不是zh_hans 或者zh_cn等等

然后,翻译对应字段的.po文件,翻译指定的字符如下:

msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-02-02 13:22+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=1; plural=0;\n"

#: .\wangzhan\templates\wangzhan\index.html:45
msgid "Select"
msgstr "选择"     

#: .\wangzhan\templates\wangzhan\index.html:58
msgid "Current language code"
msgstr "当前语言代码"

#: .\wangzhan\templates\wangzhan\index.html:59
msgid "Welcome to our page"
msgstr "欢迎访问我们的页面"

#: .\wangzhan\templates\wangzhan\index.html:61
#, python-format
msgid " %(msg)s "
msgstr ""

#: .\wangzhan\views.py:10
msgid "Welcome to China"
msgstr "欢迎来到中国北京"

自己手动翻译对应字符后,然后才可以进行下一步的编译!

2、在\xiangmu\locale\zh_HANS\LC_MESSAGES目录下,生成.mo文件
# 该命令生成一个django.mo的文件
python manage.py compilemessages

在这里插入图片描述

这个就是Django最后需要调用的翻译文件,里面包含了翻译过后的字符串列表。

重新启动服务器,就可以看到语言切换的效果了

重要提醒:

提醒(1)、windows系统下使用makemessages和compilemessages命令时会出现错误。

这是因为windows缺少基于GNU的gettext模块。安装方式如下:

  1. 下载相应版本,或者在我的分享资源下载gettext模块
    安装或解压缩到C盘或D盘, 比如C:\Program Files (x86)\gettext

  2. 把gettex下的bin地址,比如C:\Program Files (x86)\gettext\bin加入到系统PATH的环境变量
    (在控制面板>系统>高级>环境变量中添加)。

  3. 如果pycharm的terminal中运行两个命令有问题,请直接在windows的cmd窗口运行。

  4. 对于Linux系统如果缺少可以使用sudo apt-get install gettext安装。

提醒(2)、多语言国际化的时候渲染模板的方法要用render(request,’xxxxx.html’,{}),而不是render_to_response(’xxxx.html’,{})方法

提醒(3),使用 --extension 或 -e 选项指定文件扩展名来检测

django-admin.py makemessages -l de -e txt

# 用逗号和(或)使用-e 或--extension来分隔多项扩展名:
django-admin.py makemessages -l de -e html,txt -e xml

当创建JavaScript翻译目录时,你需要使用特殊的Django域:not -e js

更详细的说明,跳转官方文档查看!

相关推荐

  1. CentOS上设置中文/英文语言环境

    2024-02-03 11:20:03       40 阅读
  2. 语言游戏网站

    2024-02-03 11:20:03       42 阅读
  3. 开源大型语言模型概览:语种支持中文专注

    2024-02-03 11:20:03       32 阅读
  4. 计算机网络英文总结

    2024-02-03 11:20:03       38 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-02-03 11:20:03       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-02-03 11:20:03       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-02-03 11:20:03       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-02-03 11:20:03       20 阅读

热门阅读

  1. LeetCode 24天

    2024-02-03 11:20:03       31 阅读
  2. 【计算机安全】相关整理

    2024-02-03 11:20:03       29 阅读
  3. URL重写

    URL重写

    2024-02-03 11:20:03      34 阅读
  4. L1-054 福到了

    2024-02-03 11:20:03       30 阅读
  5. 完整的带日志的FFmpeg的命令

    2024-02-03 11:20:03       34 阅读
  6. Spring设计模式之单例模式

    2024-02-03 11:20:03       25 阅读
  7. 设计模式之-单例模式

    2024-02-03 11:20:03       32 阅读
  8. Service设计模式

    2024-02-03 11:20:03       29 阅读
  9. sklearn.preprocessing 标准化、归一化、正则化

    2024-02-03 11:20:03       28 阅读