写点什么

【Django | 开发】 (国际化项目 & 支持多语言)

  • 2022 年 8 月 30 日
    广东
  • 本文字数:4879 字

    阅读完需:约 16 分钟


🤵‍♂️ 个人主页: @计算机魔术师👨‍💻 作者简介:CSDN 内容合伙人,全栈领域优质创作者。


🌐 推荐一款找工作神器网站: 牛客网🎉🎉|笔试题库|面试经验|实习招聘内推 还没账户的小伙伴 速速点击链接跳转牛客网登录注册 开始刷爆题库,速速通关面试吧🙋‍♂️


该文章收录专栏---【Django | 项目开发】从入门到上线 专栏---


@[toc]

一、国际化项目介绍



这个翻译不是浏览器翻译的,Django 也不会帮你翻译。这个需要你自己事先手动翻译好,存放在专门翻译文件中,Django 只是事后调用而已。

二、实现步骤

2.1 为翻译字符串添加钩子

1) py 文件

将需要翻译的字符串统一使用gettext_lazygettext包裹


from django.utils.translation import gettext_lazy as _
class Candidate(models.Model): # * 基础信息 (对于整形数值一定要定义null=true,因为如果没有赋值,数据库会声明不能为null user_id = models.IntegerField(verbose_name=_('应聘者ID'), blank=True, null=True) username = models.CharField(max_length=135, verbose_name=_('姓名')) city = models.CharField(max_length=135, verbose_name=_('城市'), blank=True) phone = models.CharField(max_length=135, verbose_name=_('手机号码')) email = models.EmailField(max_length=135, verbose_name=_('邮箱'), blank=True) gender = models.CharField(max_length=135, verbose_name=_('性别'), blank=True) apply_position = models.CharField(max_length=135, verbose_name=_('应聘职位'), blank=True) born_address = models.CharField(max_length=135, verbose_name=_('生源地'), blank=True) candidate_remark = models.CharField(max_length=135, blank=True, verbose_name=_('候选人信息备注'))
复制代码

2)HTML 文件

导入i18n,为需要翻译的代码添加代码{% translate %} 或者{% blocktranslate %}用于存在变量翻译


{% load i18n %}        <div class="">          <h6 class="uppercase font-semibold mb-4 flex justify-center md:justify-start">            {% translate   "Useful links" %}          </h6>          <p class="mb-4">            <a href="#!" class="text-gray-600">{% translate   "Pricing" %}</a>          </p>          <p class="mb-4">            <a href="#!" class="text-gray-600">{% translate   "Settings" %}</a>          </p>          <p class="mb-4">            <a href="#!" class="text-gray-600">{% translate   "Orders" %}</a>          </p>          <p>            <a href="#!" class="text-gray-600">{% translate   "Help" %}</a>
-----------------------------------------------------------------------------------------------<-- 块翻译 -->{% blocktranslate with job_name=job.job_name job_city=job.job_place %} <h2>岗位名称:{{ job_name }}</h2> <div> </div> <div> 城市: {{ job_city }} </div> {% endblock %}
复制代码


如果在翻译中存在二级变量或者三级变量在渲染时需要提前保存

2.2 生成本地化翻译资源文件

  1. 在 settings 加入如下



# 默认语言LANGUAGE_CODE = 'zh-hans'
from django.utils.translation import gettext_lazy as _
LANGUAGES = [ ('en', _('English')), ('zh-hans', _('Simplified Chinese')),]# 用于存放django.po和django.mo编译过的翻译文件PROJECT_ROOT = os.path.dirname(os.path.dirname(os.path.realpath(__name__)))LOCALE_PATHS = ( os.path.join(PROJECT_ROOT, 'locale'),)
复制代码


  1. 在项目根目录下生成locale目录,用于保存翻译消息文件(.po 和.mo 格式的)

  2. 在终端输入


( 大坑插入由于在gettext版本低于0.15, 报错Make sure you have GNU gettext tools 0.15 or newer installed.,我花了一整天时间处理😑,由于支持 window 系统以及配置网上的方法都比较旧,最后还是stackoverflow香😎,直接在网址https://mlocati.github.io/articles/gettext-iconv-windows.html下载static 64文件,将其bin文件配置到系统环境变量即可!!


django-admin makemessages -l zh_Hans -l en
复制代码


  • 生成对应文件


  1. 我们需要在对应的文件中,给这些需要翻译的键添加值 ( msgid (message id)是键,msstr(message str)是值。


  • en 文件


( 这里的en 是之前所设置的名字,需要与 setting 中语言配置元组中第一个数据一样,此时我们需要都将中文翻译成英文,注意!!不进行翻译会默认使用其他语言!,例如在中文广州市翻译中翻译成了英文!


msgid "工作经验"msgstr "work-experience"
#: .\jobs\models.py:65msgid "项目经历"msgstr "product-experience"
#: .\jobs\models.py:75 .\jobs\models.py:76msgid "简历"msgstr "resume"
#: .\jobs\views.py:60msgid "job does not exist"msgstr "工作不存在"
#: .\recruitment\urls.py:34msgid "霍格沃兹学院"msgstr "Hogwarts"
#: .\recruitment\urls.py:36 .\templates\base.html:9msgid "霍格沃兹招聘信息网"msgstr "Hogwarts job list"
复制代码


  • zh_Hans 文件则翻译为中文


msgstr "忘记密码?"
#: .\templates\account\login.html:71msgid "Log In"msgstr "登 录"
#: .\templates\account\login.html:75msgid "Don't have an account?"msgstr "还没有账户?"
#: .\templates\account\login.html:75msgid "Register here."msgstr "点击注册"
#: .\templates\account\logout.html:9 .\templates\account\logout.html:12#: .\templates\account\logout.html:21msgid "Sign Out"msgstr "注销"
#: .\templates\account\logout.html:14msgid "Are you sure you want to sign out?"msgstr "你确定要注销吗"
复制代码


  1. 编译为二进制文件


django-admin compliemessages
复制代码


三、配置 settings 文件

  1. 添加路径映射


  path('i18n/', include('django.conf.urls.i18n')),
复制代码


  1. settings添加国家化的配置


# 默认语言LANGUAGE_CODE = 'en-us'
# 设置I18n和L10N为TrueUSE_I18N = TrueUSE_L10N = True
from django.utils.translation import gettext_lazy as _
LANGUAGES = [ # 第一个是对应语言,第二个是字符串表达 ('en', _('English')), ('zh-hans', _('Simplified Chinese')),]# 用于存放django.po和django.mo编译过的翻译文件LOCALE_PATHS = ( os.path.join(BASE_DIR, 'locale'),)
复制代码


  • 效果


可以看到中文都翻译成了自己翻译的英文



  1. 配置本地化中间件


LocaleMiddleware这个中间件。它的位置也很重要,应于SessionMiddleware之后,CommonMiddleware之前。(通用中间件前,改中间件主要用于一些简单处理)


MIDDLEWARE = [    'interview.performance.performance_logger_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',]
复制代码

四、让用户自己选择语言

1) 通过表单修改语言版本

添加下拉框选择语言,在base.html根模板下修改如下


{#  set language  #}<form method="POST" action="{% url "set_language" %}">    {% csrf_token %}    <input type="hidden" name="next" value="{{ redirect_to }}"/>    <select name="language">        {#    得到当前语言#}        {% get_current_language as LANGUAGE_CODE %}        {#   可用语言就是setting文件配置的元组 #}        {% 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>    {% trans "The current language:" %} {{ LANGUAGE_CODE }}    <button type="submit">{% trans "Switch" %}</button></form>
复制代码


  • 我还想美化他的样式和django文档一样



  • 实现代码如下(使用的样式是tailwind)


{#  set language  #}<div class="fixed bottom-0 right-0 mb-3 xl:w-96">    <form method="POST" action="{% url "set_language" %}" class="my-2  p-1 flex   rounded svelte-1l8159u">        {% csrf_token %}        <input type="hidden" name="next" value="{{ redirect_to }}"/>
<select name="language" class="form-select form-select-sm appearance-none block w-full px-2 py-1 text-sm font-normal text-gray-700 bg-white bg-clip-padding bg-no-repeat border border-solid border-gray-300 rounded transition ease-in-out m-0 focus:text-gray-700 focus:bg-blue focus:border-blue-600 focus:outline-none"> {# 得到当前语言#} {% get_current_language as LANGUAGE_CODE %} {# 可用语言就是setting文件配置的元组 #} {% 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 %}> {% trans "The current language:" %} {{ language.name_local }} {{ language.code }} </option> {% endfor %} </select> <button type="submit" class="inline-block px-4 py-1.5 bg-blue-600 text-white font-medium text-xs leading-tight uppercase rounded shadow-md hover:bg-blue-700 hover:shadow-lg focus:bg-blue-700 focus:shadow-lg focus:outline-none focus:ring-0 active:bg-blue-800 active:shadow-lg transition duration-150 ease-in-out">{% trans "Switch" %}</button> </form></div>
复制代码


  • 效果

2)通过对应链接修改

其实django官方文档的国家化项目中也是这么干的


这里需要添加路由url i18n_patterns


from django.contrib import adminfrom django.urls import path, includefrom 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')),)
复制代码


这样在不同路径下,就会切换语言,但是目前是需要全部项目的路由都要修改,不知道如何配置才不需要😂(参考文章: 大江狗 | 刘江的博客

小结

  • Django 如何识别用什么语言呢?


django 查询语言是先从url找,然后再从cookie里面找,再从浏览器header里面找,如果都没有的话则使用系统默认语言LANGUAGE_CODE


  • Django 如何切换语言?


在切换语言 from 表单中,我们所提交的表单路径set_language 是我们所导入i18n url 路径所提供的,提交的language.code能够对应到我们所设置的语言就能切换语言。



              🤞到这里,如果还有什么疑问🤞    🎩欢迎私信博主问题哦,博主会尽自己能力为你解答疑惑的!🎩      🥳如果对你有帮助,你的赞是对博主最大的支持!!🥳
复制代码


用户头像

还未添加个人签名 2022.08.13 加入

还未添加个人简介

评论

发布
暂无评论
【Django | 开发】 (国际化项目&支持多语言)_8月月更_计算机魔术师_InfoQ写作社区