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

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

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

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

python 复制代码
# 引入模块
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这个方法,而是使用

python 复制代码
# 开头先要引入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/ 等

python 复制代码
# 项目下的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')),
)
python 复制代码
# 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"。

python 复制代码
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调用标签

python 复制代码
<!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文件
python 复制代码
# 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文件
python 复制代码
# 该命令生成一个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 选项指定文件扩展名来检测

python 复制代码
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

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

相关推荐
月光水岸New1 小时前
Ubuntu 中建的mysql数据库使用Navicat for MySQL连接不上
数据库·mysql·ubuntu
狄加山6751 小时前
数据库基础1
数据库
我爱松子鱼1 小时前
mysql之规则优化器RBO
数据库·mysql
chengooooooo2 小时前
苍穹外卖day8 地址上传 用户下单 订单支付
java·服务器·数据库
Rverdoser3 小时前
【SQL】多表查询案例
数据库·sql
Galeoto3 小时前
how to export a table in sqlite, and import into another
数据库·sqlite
人间打气筒(Ada)3 小时前
MySQL主从架构
服务器·数据库·mysql
leegong231113 小时前
学习PostgreSQL专家认证
数据库·学习·postgresql
喝醉酒的小白3 小时前
PostgreSQL:更新字段慢
数据库·postgresql
敲敲敲-敲代码3 小时前
【SQL实验】触发器
数据库·笔记·sql