LANGUAGE_CODE[1]
LANGUAGE_CODE 是 language code 的字符串。格式與 Accept-Language HTTP header 相同,不區分大小寫,比如:zh, es, zh-hans
。所有的 language codes 見 http://www.i18nguy.com/unicode/language-identifiers.html 。
Django LANGUAGE_CODE 有兩個作用:
- 如果沒有設置 locale 中間件,那么這個用於給所有用戶提供翻譯。適用於只需要一種翻譯的情況
- 如果設置了 locale 中間件,那么作為翻譯的后備物品,用於沒有匹配到語言的情況
LocaleMiddleware 決定用戶語言的算法,順序為 URL 語言前綴、session、cookie、Accept-Language HTTP 頭部,最后是 LANGUAGE_CODE[2]。
注意:Django 的 LANGUAGE_CODE 是不區分大小的,但第三方 APP 就不一定了,比如 django-ckeditor
只有在 LANGUAGE_CODE 為 zh-hans
時翻譯才會生效,所以它是區分大小寫的。
尋找翻譯的算法
在運行時,Django 會構建一個在內存中的、統一的文字翻譯目錄。依次在以下路徑中加載信息文件(.mo)以及對同一字符串的翻譯優先級如果對統一字符串存在多個翻譯:
- LOCALE_PATHS 有最高優先級,在 LOCALE_PATHS 中出現在前面的優先級更高。
- 然后查看 INSTALLED_APPS 中各個 APP 目錄下的 locale/,也是在前面的 APP 優先級高
- 最后,
django/conf/locale
作為后備
存放翻譯文件的目錄名為 locale name。在我看來就是將對應的 language code 的 -
替換為 _
。比如 language code zh-Hans
的 locale name 為 zh_Hans
。這點可以在 Django 自己的翻譯中得到驗證,比如 env/lib/python3.6/site-packages/django/conf/locale/zh_Hans
。
替換虛擬環境中第三方 APP 的翻譯
我將第三方 APP 的替代翻譯放在 LOCALE_PATHS 中,但只有在 env/
在和 manage.py
同目錄的情況下才能生效。不清楚這樣的原因,因為按照上面的算法,LOCALE_PATHS 的優先級是最高的。
目前采用的辦法是,fork 該第三方 APP,然后將翻譯直接放到第三方 APP 的 locale 中,然后使用 submodule 安裝 fork 后的第三方庫。