Django进阶 ----国际化

1. 说明

  • 实现中英对照翻译,但这个翻译不是浏览器翻译的,Django也不会帮你翻译。这个需要你自己事先手动翻译好,存放在专门翻译文件中,Django只是调用而已
  • 对于需要翻译的字符串要事先标记好
  • 标记方法(标记不是翻译): .py 文件中使用 ugettext_lazy() 方法; .html 文件中使用 {% trans “string” %}, {% blocktrans%} {%endblocktrans %} 这两个标签,使用该标签需在模板的最开始地方加入 {% load i18n %}

2. 流程

1. 修改settings.py配置

  • 在myproject 项目目录下新建 locale 文件夹,用于保存翻译消息文件(.po和.mo格式的)
  • 修改配置文件 settings.py
from django.utils.translation import ugettext_lazy as _

# 默认语言
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'),
)
  • ugettext_lazy 这个方法,它的作用是在.py文件文件标记需要翻译的字符串,对其进行惰性参照存储,而不是对字符串进行真正的翻译
  • 需要在 SessionMiddleware 之后, CommonMiddleware 之前,加入 LocaleMiddleware 中间件
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.locale.LocaleMiddleware', # 新增多语支持
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

2. 修改项目的urls.py

  • 修改项目目录urls.py
  • i18n_patterns 的作用是让每个url前面自动加上所选语言的代码,比如 /en/ , /zh-hans/ 等
  • 分别访问 http://127.0.0.1:8000/en/admin/ 和 http://127.0.0.1:8000/zh-hans/admin/ 将看到不同语言版本
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('myapp.urls')),
)

3. 标记需要翻译的字符串

  • 在python文件中使用 ugettext_lazy 方法或则简写的 _,在html和txt文件中使用 trans 标签blocktrans 标签, 使用前还需在文件开头加入 {% load i18n %}
  • 一个是用于模板中已存在的字符串,一个是用于视图函数传递过来的变量
# 视图中使用 ugettext_lazy 方法标记

# myapp/views.py
from django.shortcuts import render
from django.utils.translation import ugettext_lazy as _

# Create your views here.
def index(request):
    context = {'msg': _("Welcome to China")}
    return render(request, 'myapp/index.html', context)
# html中使用标签标记,标准模板

<!DOCTYPE html>
{% load static %}
{% load i18n %}
{% load core_tags_filters %}
<html lang="en">
  <head>
   <meta charset="utf-8">
   <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
   <meta name="description" content="">
   <title>Django房产网</title>
   <link rel="canonical" href="https://getbootstrap.com/docs/4.5/examples/">
   <!-- Bootstrap core CSS -->
   <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
      <style>
   body {
      overflow-x: hidden; /* Prevent scroll on narrow devices */
     font-family: 'Inter', Arial, sans-serif;
     background: #F6F8FF;
     padding-top: 56px;
   }
</style>
  </head>
  <body>
     <nav class="navbar navbar-expand-md fixed-top navbar-light box-shadow bg-white">
     <div class="container">
       <a class="navbar-brand align-items-md-center" href="index.html">Django双语示例</a>
           <form class="form-inline ml-3-md" 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 }}
                            </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>
     </div>
    </nav>
  {% 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 }}</b> </h4>
         <p><small>{% trans "Welcome to our page" %}</small></p>
         <hr/>
         <p>{% blocktrans %} {{ msg }} {% endblocktrans %}</p>
     </div>
</div>
{% endblock %}


<footer class="bd-footer bg-light">
    <div class="container pt-3 pb-2 px-3 px-md-2">
      <ul class="bd-footer-links list-unstyled text-muted list-inline pb-2">
        <li class="list-inline-item">
        <small>&#169; Example.com</small>
        </li>
        <li class="list-inline-item right"><a href="https://twitter.com/getbootstrap"><small>{% trans 'Privacy and Cookie' %}</small></a></li>
        <li class="list-inline-item right"><a href="/docs/4.5/examples/"><small>{% trans 'Terms and Conditions' %}</small></a></li>
      </ul>
   </div>
</footer>
  <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>
</html> 

4. 生成 .po 和 .mo 编译消息文件

  • 对前面标记的字符串进行手动翻译,并生成编译过后的消息文件供Django使用
  1. 进入项目文件夹,使用 django-admin makemessages -l zh_HANS 命令提取所有前面标记需要翻译的字符串。该命令会自动在 locale 文件夹下生成一个名为 django.po 的文件,但翻译内容为空

    #: .\house\templates\house\index.html:27
    msgid "Welcome to our page"
    msgstr ""
    
    
    #: .\house\templates\house\index.html:29 .\house\templates\house\index1.html:65
    #, python-format
    msgid " %(msg)s "
    msgstr ""
    
    
    #: .\house\templates\house\index1.html:48
    msgid "Select"
    msgstr ""
    
    
    #: .\house\templates\house\index1.html:60
    #, fuzzy
    msgid "Welcome to our website"
    msgstr ""
    
  2. 修改django.po文件,添加手动翻译的字符串

    #: .\house\templates\house\index.html:27
    msgid "Welcome to our page"
    msgstr "欢迎来到我们主页"
    
    #: .\house\templates\house\index.html:29 .\house\templates\house\index1.html:65
    #, python-format
    msgid " %(msg)s "
    msgstr ""
    
    #: .\house\templates\house\index1.html:48
    msgid "Select"
    msgstr "选择"
    
    #: .\house\templates\house\index1.html:60
    #, fuzzy
    msgid "Welcome to our website"
    msgstr "欢迎来到我们网站"
    
  3. 使用 python manage.py compilemessages 命令生成翻译编译文件 django.mo,这是Django最后需调用的翻译文件,里面包含了翻译过后的字符串列表

    Report-Msgid-Bugs-To: 
    PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE
    Last-Translator: FULL NAME <EMAIL@ADDRESS>
    Language-Team: LANGUAGE <LL@li.org>
    Language: 
    MIME-Version: 1.0
    Content-Type: text/plain; charset=UTF-8
    Content-Transfer-Encoding: 8bit
    Plural-Forms: nplurals=1; plural=0;
     当前语言代码 英语 隐私与Cookie 选择 简体中文 服务条款与协议 欢迎来到中国 欢迎来到我们主页
    

3. 注意事项

  • 1.i18n国际化(Internationalization)的缩写。i 和 n 之间有 18 个字母,简称 I18N,。l10n本地化(localization)的缩写。l 和 n 之间有 10 个字母,简称 L10N。
  • 2.windows系统下使用 makemessagescompilemessages 命令时会出现错误,这是因为windows缺少基于GNU的 gettext 模块。安装方式如下:
    • https://mlocati.github.io/articles/gettext-iconv-windows.html下载相应版本,安装或解压缩到C盘或D盘, 比如C:\Program Files (x86)\gettext

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

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

  • 3.Linux系统如果缺少可以使用sudo apt-get install gettext安装
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值