django 進行語言的國際化及在後臺進行中英文切換

項目的部署地爲: 中國大陸與美國東海岸, 兩個地區的服務器數據不進行同步, 中國地區的服務器頁面展現中文, 美國地區的服務器頁面展現成英文, 項目後臺使用python編程語言進行開發, 並結合django框架進行版本迭代.

這裏對項目的國際化進行配置說明:


一.在配置文件settings.py中:

1) 開啓國際化功能

    # 語言, 先設置成中文
    LANGUAGE_CODE = 'zh-hans'  # 1.8版本以後的language code設置不一樣, 1.8以前是LANGUAGE_CODE = 'zh-CN'
    # LANGUAGE_CODE = 'en'
     
    # 時區
    TIME_ZONE = 'Asia/Shanghai'
    # TIME_ZONE = 'UTC'
     
    # Internationalization
    # https://docs.djangoproject.com/en/2.1/topics/i18n/
    # 開啓國際化
    USE_I18N = True
     
    # 開啓本地化
    USE_L10N = True
     
    USE_TZ = True
     
    LANGUAGES = (
       ('en', 'English'),
       ('zh-hans', '中文簡體'),
    )
     
    # 翻譯文件所在目錄, 與 manage.py 文件在同級目錄下
    LOCALE_PATHS = (
        os.path.join(BASE_DIR, 'locale'),
    )

2) 添加進行國際化的中間件

    MIDDLEWARE = [
        'django.middleware.security.SecurityMiddleware',
        'django.contrib.sessions.middleware.SessionMiddleware',
        # 這就是新添加進來的中間件, 注意位置: 須要放置在 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',
    ]

3) 添加i18n上下文渲染器

    TEMPLATES = [
        {
            'BACKEND': 'django.template.backends.django.DjangoTemplates',
            'DIRS': [os.path.join(BASE_DIR, 'templates')],
            'APP_DIRS': True,
            'OPTIONS': {
                'context_processors': [
                    # 新添加進來的上下文渲染器, 不知是不是本人配置不當, 若是將該渲染器放置在其餘位置, 沒法進行語言切換
                    'django.template.context_processors.i18n',
                    'django.template.context_processors.debug',
                    'django.template.context_processors.request',
                    'django.contrib.auth.context_processors.auth',
                    'django.contrib.messages.context_processors.messages',
                ],
            },
        },
    ]


二.在項目的路由文件 urls.py中, 添加路由:

    # 若是須要支持在頁面自由選擇語言進行切換, 必須添加該路由, 獲取語言翻譯文件
    url(r'^i18n/', include('django.conf.urls.i18n')),


三.在模板文件中開啓國際化

    <!DOCTYPE html>
     
    {% load i18n %}

在須要進行國際化的模板中開啓國際化功能: 在文件的開頭添加: {% load i18n %}, 也能夠放置在 <!DOCTYPE html> 後面


四.添加須要進行國際化的字符串

1) 在視圖中調用模板, 經過變量賦值渲染模板( 或者直接返回json數據給前臺, 由前臺經過js或者其餘模塊進行翻譯):

在views.py中:

    from django.utils.translation import gettext_lazy as _
     
        ...
        if user.is_active:
            # _("已激活") 標示對該字符串進行國際化翻譯, 若是是先後端分離,使用 gettext_lazy() 進行國際化翻譯之後, 就能夠轉換成json數據向前臺返回了
            context = {"text": _("已激活"),"domain": domain}
            # 進行模板渲染,響應用戶請求.若是先後分離,能夠直接返回json數據給前端,由前端在js中進行國際化
            return render(request, "./users/active_account.html", context)

若是是模板渲染, 在相應的模板文件 acitveacitve_account.html 中:

    <body>
        <h2>{%trans "你好!" %}</h2>
        <h2>{{ text }}</h2>
        <img src="{{ domain }}/static/images/qcat2.jpeg" alt="">
    </body>

直接將變量渲染到模板中便可, 由模板調用翻譯文件進行翻譯.

若是須要進行國際化的字符串能夠直接寫死在模板中, 也能夠直接在模板中使用下面的方式進行國際化:

{%trans "須要翻譯的字符串" %} , 如上面的代碼中所示.


五.生成翻譯文件(先在manage.py的同級目錄下建立 locale目錄)

python manage.py makemessages -l en

會在locale目錄下生成 po 翻譯文件, 文件自動列出須要進行翻譯的字符串, 如:

    # 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: 2019-04-17 03:06+0000\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"
     
    #: apps/users/models.py:25
    msgid "郵箱地址"
    msgstr ""
     
    #: apps/users/views.py:748
    msgid "已激活"
    msgstr ""
     
     
    #: templates/users/active_account.html:10
    msgid "你好!"
    msgstr ""

msgid : 須要進行國際化的字符串

msgstr: 將翻譯好的字符串, 填充進去便可,如:

    # 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: 2019-04-17 03:06+0000\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"
     
    msgid "郵箱地址"
    msgstr "email"
     
    #: apps/users/views.py:748
    msgid "已激活"
    msgstr "You have successfully activated the account, do not need to activete it again, thank you!"
     
    #: templates/users/active_account.html:10
    msgid "你好!"
    msgstr "hello"

編譯po文件, 在locale所在目錄下執行下面的命令:

python manage.py compilemessages

到這裏, 國際化的配置基本完成, 能夠經過修改下面的配置項,進行平臺語言展現的設置

    # 中文
    LANGUAGE_CODE = 'zh-hans'  # 1.8版本以後的language code設置不一樣, 1.8以前是LANGUAGE_CODE = 'zh-CN'
    # LANGUAGE_CODE = 'en'
     
    # 時區
    TIME_ZONE = 'Asia/Shanghai'
    # TIME_ZONE = 'UTC'

以下所示

中文:

    你好!
    已激活

英文:

    hello
    You have successfully activated the account, do not need to activete it again, thank you!

若是須要在頁面中讓用戶自行選擇進行語言切換, 還須要進行額外的配置, 詳情能夠去查看官方文檔
 

六.若是前臺是APP,語言切換時,由於先後臺的語言環境須要保持一直,因此我這裏採起了一種不是太優雅的的辦法: 封裝一個接口, 當用戶進行國際化切換時,由APP請求一下該接口, 告知後臺該用戶選擇了那種語言, 接口代碼以下所示:

    @api_view(["POST"])
    def set_lang(request):
        """
        用戶在app進行語言切換時, 請求一下該接口
        :param request:
        :return:
        """
        language = request.data.get("language", "en")
     
        if language == "zh-hans":
            request.session['_language'] = "zh-hans"
        else:
            request.session['_language'] = "en"
     
        return Response({"msg": "Ok"}, status=status.HTTP_200_OK)

當用戶請求其餘接口時,就能夠經過request請求對象獲取到用戶當前是選擇的那種語言(即便不進行登陸也能夠獲取到):

language = request.LANGUAGE_CODE
相關文章
相關標籤/搜索