暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Djoser:本地化语言支持

Nephilim 2024-05-27
113

Tips:一些记录,一些笔记



2024/05/27

MONDAY

杜牧说「东风不与周郎便,铜雀春深锁二乔」




01

Djoser


Djoser默认情况下是英文版的,比如下面这个报错,默认是以英文方式输出的:


02

Djoser的本地化支持


打开你的Django项目的「venv」你可以找到通过PIP安装的Djoser的目录:

可以看到,每一个语言对应的目录中都包含一个名为「django.po」的文件。


该文件中定义了本地化翻译的对应关系:

  • msgid:英文原文

  • msgstr:翻译后的本地化字符串


例如,德语的「django.po」文件的完整内容如下所示:

    # Copyright (C) Sunscrapers
    # This file is distributed under the same license as the djoser package.
    #
    # Translators:
    # Bertram Bühner <github@sheepyhollow.de>, 2020
    #
    #, fuzzy
    msgid ""
    msgstr ""
    "Project-Id-Version: djoser\n"
    "Report-Msgid-Bugs-To: \n"
    "POT-Creation-Date: 2020-01-13 17:40+0100\n"
    "Last-Translator: Bertram Bühner <github@sheepyhollow.de>\n"
    "Language-Team: German\n"
    "Language: de\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"


    #: constants.py:4
    msgid "Unable to log in with provided credentials."
    msgstr "Eine Anmeldung ist mit den angegebenen Daten nicht möglich."


    #: constants.py:5
    msgid "User account is disabled."
    msgstr "Dieses Benutzerkonto ist deaktiviert."


    #: constants.py:6
    msgid "Invalid token for given user."
    msgstr "Das Token für diesen Benutzer ist ungültig."


    #: constants.py:7
    msgid "Invalid user id or user doesn't exist."
    msgstr "Die User-ID ist ungültig oder dieser Benutzer existiert nicht."


    #: constants.py:8
    msgid "Stale token for given user."
    msgstr "Das Token für diesen Benutzer ist abgelaufen."


    #: constants.py:9
    msgid "The two password fields didn't match."
    msgstr "Die beiden Passwörter stimmen nicht überein."


    #: constants.py:10
    #, python-brace-format
    msgid "The two {0} fields didn't match."
    msgstr "Die beiden {0}-Felder stimmen nicht überein."


    #: constants.py:11
    msgid "Invalid password."
    msgstr "Das Passwort ist ungültig."


    #: constants.py:12
    msgid "User with given email does not exist."
    msgstr "Es existiert kein Benutzer mit dieser E-Mailadresse."


    #: constants.py:13
    msgid "Unable to create account."
    msgstr "Das Benutzerkonto kann nicht angelegt werden."


    #: constants.py:15
    msgid ""
    "User model does not contain specified email field. Please see http://djoser."
    "readthedocs.io/en/latest/settings.html#USER_EMAIL_FIELD_NAME for more "
    "details."
    msgstr ""
    "Das user-model enthält kein E-Mail-Feld. Weitere Details unter "
    "http://djoser.readthedocs.io/en/latest/settings.html#USER_EMAIL_FIELD_NAME "
    "."


    #: templates/email/activation.html:4
    #, python-format
    msgid "Account activation on %(site_name)s"
    msgstr "Aktivierung des Benutzerkontos auf %(site_name)s"


    #: templates/email/activation.html:8 templates/email/activation.html:19
    #, python-format
    msgid ""
    "You're receiving this email because you need to finish activation process on "
    "%(site_name)s."
    msgstr ""
    "Sie erhalten diese E-Mail, da Sie den Aktivierungsprozess auf %(site_name)s."
    "abschließen müssen."


    #: templates/email/activation.html:10 templates/email/activation.html:22
    msgid "Please go to the following page to activate account:"
    msgstr "Bitte begeben Sie sich auf folgende Seite, um die Aktivierung abzuschließen:"


    #: templates/email/activation.html:13 templates/email/activation.html:25
    #: templates/email/confirmation.html:10 templates/email/confirmation.html:18
    #: templates/email/password_reset.html:14
    #: templates/email/password_reset.html:26
    msgid "Thanks for using our site!"
    msgstr "Vielen Dank für die Nutzung unserer Seite!"


    #: templates/email/activation.html:15 templates/email/activation.html:27
    #: templates/email/confirmation.html:12 templates/email/confirmation.html:20
    #: templates/email/password_reset.html:16
    #: templates/email/password_reset.html:28
    #, python-format
    msgid "The %(site_name)s team"
    msgstr "Das Team von %(site_name)s"


    #: templates/email/confirmation.html:4
    #, python-format
    msgid ""
    "%(site_name)s - Your account has been successfully created and activated!"
    msgstr ""
    "%(site_name)s - Ihr Benutzerkonto wurde erfolgreich erstellt und aktiviert!"


    #: templates/email/confirmation.html:8 templates/email/confirmation.html:16
    msgid "Your account has been created and is ready to use!"
    msgstr "Ihr Benutzerkonto wurde erstellt und ist freigeschaltet!"


    #: templates/email/password_reset.html:4
    #, python-format
    msgid "Password reset on %(site_name)s"
    msgstr "Zurücksetzen des Passworts auf %(site_name)s"


    #: templates/email/password_reset.html:8 templates/email/password_reset.html:20
    #, python-format
    msgid ""
    "You're receiving this email because you requested a password reset for your "
    "user account at %(site_name)s."
    msgstr ""
    "Sie erhalten diese E-Mail, da Sie das Zurücksetzen Ihres Passworts auf "
    "%(site_name)s angefordert haben."


    #: templates/email/password_reset.html:10
    #: templates/email/password_reset.html:22
    msgid "Please go to the following page and choose a new password:"
    msgstr "Bitte geben Sie auf der folgenden Seite ein neues Passwort ein:"


    #: templates/email/password_reset.html:12
    #: templates/email/password_reset.html:24
    msgid "Your username, in case you've forgotten:"
    msgstr "Ihr Benutzername - falls Sie ihn vergessen haben - lautet:"



    默认情况下,Djoser支持的语言如下所示:

    可以看到,其中并不包含中文(zh-hans)


    这里的语言编码的简写是与Django本身的语言代码(LANGUAGE_CODE)保持一致的。


    Django中的LANGUAGE_CODE:

    https://docs.djangoproject.com/en/5.0/ref/settings/#language-code


    支持的语言代码完整列表:

    http://www.i18nguy.com/unicode/language-identifiers.html


    03

    实现「中文」本地化支持


    在了解了Djoser官方的源码是如何实现语言的本地化支持后,我们就可以按照一样的方式,扩展「中文」的本地化支持了。


    前面访问的路径是第三方包的安装目录,我们不对别人的源码修改,避免出现不必要的麻烦与不可预期的错误。


    首先,在自己的项目中创建路径「locale」


    注意,上面这里有个错误,创建本地化相关路径的时候,不能带上「__init__.py」文件,否则你将会遇到如下文所示的错误:

    Django: module 'locale' has no attribute 'normalize'


    正确的路径:

    语言代码中如果有「-」在设置文件路径名称的时候,应该替换为「下划线」


    编辑其中的本地化文件「django.po」:

      # Copyright (C) Sunscrapers
      # This file is distributed under the same license as the djoser package.
      #
      msgid ""
      msgstr ""
      "Project-Id-Version: djoser\n"
      "Report-Msgid-Bugs-To: \n"
      "POT-Creation-Date: 2024-05-27 15:06-1800\n"
      "Last-Translator: Adamhuan <dkseven_eli@163.com>\n"
      "Language-Team: Chinese\n"
      "Language: zh-hans\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"


      #: djoser/constants.py:4
      msgid "No active account found with the given credentials"
      msgstr "不正确的身份验证"


      #: djoser/constants.py:5
      msgid "Unable to log in with provided credentials."
      msgstr "无法使用提供的凭据登录."


      #: djoser/constants.py:6
      msgid "User account is disabled."
      msgstr "禁用用户帐户."


      #: djoser/constants.py:7
      msgid "Invalid token for given user."
      msgstr "给定用户的令牌无效."


      #: djoser/constants.py:8
      msgid "Invalid user id or user doesn't exist."
      msgstr "无效的用户id或用户不存在."


      #: djoser/constants.py:9
      msgid "Stale token for given user."
      msgstr "给定用户的陈旧令牌."


      #: djoser/constants.py:10
      msgid "The two password fields didn't match."
      msgstr "两个密码字段不匹配."


      #: djoser/constants.py:11
      #, python-brace-format
      msgid "The two {0} fields didn't match."
      msgstr "两个{0}字段不匹配."


      #: djoser/constants.py:12
      msgid "Invalid password."
      msgstr "无效的密码."


      #: djoser/constants.py:13
      msgid "User with given email does not exist."
      msgstr "给定电子邮件的用户不存在."


      #: djoser/constants.py:14
      msgid "Unable to create account."
      msgstr "无法创建帐户."


      #: djoser/templates/email/activation.html:4
      #, python-format
      msgid "Account activation on %(site_name)s"
      msgstr "激活账户 %(site_name)s"


      #: djoser/templates/email/activation.html:8
      #: djoser/templates/email/activation.html:19
      #, python-format
      msgid ""
      "You're receiving this email because you need to finish activation process on "
      "%(site_name)s."
      msgstr ""
      "你收到这封邮件是因为你需要完成激活过程 "
      "%(site_name)s."


      #: djoser/templates/email/activation.html:10
      #: djoser/templates/email/activation.html:21
      msgid "Please go to the following page to activate account:"
      msgstr "请到以下页面激活帐户:"


      #: djoser/templates/email/activation.html:13
      #: djoser/templates/email/activation.html:24
      #: djoser/templates/email/confirmation.html:10
      #: djoser/templates/email/confirmation.html:18
      #: djoser/templates/email/password_changed_confirmation.html:10
      #: djoser/templates/email/password_changed_confirmation.html:18
      #: djoser/templates/email/password_reset.html:14
      #: djoser/templates/email/password_reset.html:26
      #: djoser/templates/email/username_changed_confirmation.html:10
      #: djoser/templates/email/username_changed_confirmation.html:18
      #: djoser/templates/email/username_reset.html:14
      #: djoser/templates/email/username_reset.html:26
      msgid "Thanks for using our site!"
      msgstr "感谢使用我们的网站!"


      #: djoser/templates/email/activation.html:15
      #: djoser/templates/email/activation.html:26
      #: djoser/templates/email/confirmation.html:12
      #: djoser/templates/email/confirmation.html:20
      #: djoser/templates/email/password_changed_confirmation.html:12
      #: djoser/templates/email/password_changed_confirmation.html:20
      #: djoser/templates/email/password_reset.html:16
      #: djoser/templates/email/password_reset.html:28
      #: djoser/templates/email/username_changed_confirmation.html:12
      #: djoser/templates/email/username_changed_confirmation.html:20
      #: djoser/templates/email/username_reset.html:16
      #: djoser/templates/email/username_reset.html:28
      #, python-format
      msgid "The %(site_name)s team"
      msgstr "团队 %(site_name)s"


      #: djoser/templates/email/confirmation.html:4
      #, python-format
      msgid ""
      "%(site_name)s - Your account has been successfully created and activated!"
      msgstr "%(site_name)s - 您已成功激活账号!"


      #: djoser/templates/email/confirmation.html:8
      #: djoser/templates/email/confirmation.html:16
      msgid "Your account has been created and is ready to use!"
      msgstr "您的帐户已经创建,可以使用了!"


      #: djoser/templates/email/password_changed_confirmation.html:4
      #, python-format
      msgid "%(site_name)s - Your password has been successfully changed!"
      msgstr "%(site_name)s - 您已成功修改密码!"


      #: djoser/templates/email/password_changed_confirmation.html:8
      #: djoser/templates/email/password_changed_confirmation.html:16
      msgid "Your password has been changed!"
      msgstr "Su contraseña ha sido cambiada!"


      #: djoser/templates/email/password_reset.html:4
      #, python-format
      msgid "Password reset on %(site_name)s"
      msgstr "Reseteo de contraseña en %(site_name)s"


      #: djoser/templates/email/password_reset.html:8
      #: djoser/templates/email/password_reset.html:20
      #, python-format
      msgid ""
      "You're receiving this email because you requested a password reset for your "
      "user account at %(site_name)s."
      msgstr ""
      "您收到这封邮件是因为您请求重置您的"
      "用户帐户在 %(site_name)s"


      #: djoser/templates/email/password_reset.html:10
      #: djoser/templates/email/password_reset.html:22
      msgid "Please go to the following page and choose a new password:"
      msgstr "请进入以下页面并选择新密码"


      #: djoser/templates/email/password_reset.html:12
      #: djoser/templates/email/password_reset.html:24
      #: djoser/templates/email/username_reset.html:12
      #: djoser/templates/email/username_reset.html:24
      msgid "Your username, in case you've forgotten:"
      msgstr "你的用户名,以防你忘了:"


      #: djoser/templates/email/username_changed_confirmation.html:4
      #, python-format
      msgid "%(site_name)s - Your username has been successfully changed!"
      msgstr "%(site_name)s - 您已成功修改了用户名!"


      #: djoser/templates/email/username_changed_confirmation.html:8
      #: djoser/templates/email/username_changed_confirmation.html:16
      msgid "Your username has been changed!"
      msgstr "Su usuario ha sido cambiado!"


      #: djoser/templates/email/username_reset.html:4
      #, python-format
      msgid "Username reset on %(site_name)s"
      msgstr "用户名重置 %(site_name)s"


      #: djoser/templates/email/username_reset.html:8
      #: djoser/templates/email/username_reset.html:20
      #, python-format
      msgid ""
      "You're receiving this email because you requested a username reset for your "
      "user account at %(site_name)s."
      msgstr ""
      "你收到这封邮件是因为你请求重置你的用户名在 %(site_name)s"


      #: djoser/templates/email/username_reset.html:10
      #: djoser/templates/email/username_reset.html:22
      msgid "Please go to the following page and choose a new username:"
      msgstr "请进入以下页面并选择一个新用户名:"


      然后,在Django的全局配置文件「settings.py」中进行配置:

        LOCALE_PATHS = [
        Path(BASE_DIR).joinpath('locale')
        ]


        然后,通过Django的django-admin生成本地化代码运行时的「.mo」文件:

          (venv) (base) adamhuan@Leviathan django_daily_media % ls -ltr locale/zh-hans/LC_MESSAGES 
          total 24
          -rw-r--r-- 1 adamhuan staff 391 May 27 14:53 __init__.py
          -rw-r--r-- 1 adamhuan staff 6629 May 27 15:09 django.po
          (venv) (base) adamhuan@Leviathan django_daily_media %
          (venv) (base) adamhuan@Leviathan django_daily_media % django-admin compilemessages --locale=zh-hans
          processing file django.po in Users/adamhuan/PycharmProjects/django_daily_media/locale/zh-hans/LC_MESSAGES
          (venv) (base) adamhuan@Leviathan django_daily_media %
          (venv) (base) adamhuan@Leviathan django_daily_media % ls -ltr locale/zh-hans/LC_MESSAGES
          total 32
          -rw-r--r-- 1 adamhuan staff 391 May 27 14:53 __init__.py
          -rw-r--r-- 1 adamhuan staff 6629 May 27 15:09 django.po
          -rw-r--r-- 1 adamhuan staff 3374 May 27 15:45 django.mo
          (venv) (base) adamhuan@Leviathan django_daily_media %

          需要注意的是「每次 po 文件的修改」都需要重新进行重新编译,生成对应的「mo」文件。


          然后,重新运行Django项目:


          04

          看看效果


          可以看到,Djoser的提示信息已经变成中文了。


          它在本地化文件中定义的位置:





          END




          温馨提示



          如果你喜欢本文,请分享到朋友圈,想要获得更多信息,请关注我。


          文章转载自Nephilim,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

          评论