在這些功能背后,Django擁有一個靈活的模型來確定在安裝和使用應(yīng)用程序的過程中選擇使用的語言。
要設(shè)定一個安裝階段的語種偏好,請?jiān)O(shè)定LANGUAGE_CODE。如果其他翻譯器沒有找到一個譯文,Django將使用這個語種作為缺省的翻譯最終嘗試。
如果你只是想要用本地語言來運(yùn)行Django,并且該語言的語言文件存在,只需要簡單地設(shè)置 LANGUAGE_CODE 即可。
如果要讓每一個使用者各自指定語言偏好,就需要使用 LocaleMiddleware 。 LocaleMiddleware 使得Django基于請求的數(shù)據(jù)進(jìn)行語言選擇,從而為每一位用戶定制內(nèi)容。 它為每一個用戶定制內(nèi)容。
使用 LocaleMiddleware 需要在 MIDDLEWARE_CLASSES 設(shè)置中增加 'django.middleware.locale.LocaleMiddleware' 。 中間件的順序是有影響的,最好按照依照以下要求:
保證它是第一批安裝的中間件類。
因?yàn)?LocalMiddleware 要用到session數(shù)據(jù),所以需要放在 SessionMiddleware 之后。
如果你使用CacheMiddleware,把LocaleMiddleware放在它后面。
例如, MIDDLE_CLASSES 可能會是如此:
MIDDLEWARE_CLASSES = ( 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.locale.LocaleMiddleware', 'django.middleware.common.CommonMiddleware', )
LocaleMiddleware 按照如下算法確定用戶的語言:
備注:
在上述每一處,語種偏好應(yīng)作為字符串,以標(biāo)準(zhǔn)的語種格式出現(xiàn)。 例如,巴西葡萄牙語是pt-br
如果一個基本語種存在而亞語種沒有指定,Django將使用基本語種。 比如,如果用戶指定了 de-at (澳式德語)但Django只有針對 de 的翻譯,那么 de 會被選用。
只有在 LANGUAGES 設(shè)置中列出的語言才能被選用。 若希望將語言限制為所提供語言中的某些(因?yàn)閼?yīng)用程序并不提供所有語言的表示),則將 LANGUAGES 設(shè)置為所希望提供語言的列表,例如: 例如:
LANGUAGES = ( ('de', _('German')), ('en', _('English')), )
上面這個例子限制了語言偏好只能是德語和英語(包括它們的子語言,如 de-ch 和 en-us )。
如果自定義了 LANGUAGES ,將語言標(biāo)記為翻譯字符串是可以的,但是,請不要使用 django.utils.translation 中的 gettext() (決不要在settings文件中導(dǎo)入 django.utils.translation ,因?yàn)檫@個模塊本身是依賴于settings,這樣做會導(dǎo)致無限循環(huán)),而是使用一個“虛構(gòu)的” gettext() 。
解決方案就是使用一個“虛假的” gettext() 。以 下是一個settings文件的例子:
ugettext = lambda s: s LANGUAGES = ( ('de', ugettext('German')), ('en', ugettext('English')), )
這樣做的話, make-messages.py 仍會尋找并標(biāo)記出將要被翻譯的這些字符串,但翻譯不會在運(yùn)行時進(jìn)行,故而需要在任何使用 LANGUAGES 的代碼中用“真實(shí)的” ugettext()。
LocaleMiddleware 只能選擇那些Django已經(jīng)提供了基礎(chǔ)翻譯的語言。 如果想要在應(yīng)用程序中對Django中還沒有基礎(chǔ)翻譯的語言提供翻譯,那么必須至少先提供該語言的基本的翻譯。 例如,Django使用特定的信息ID來翻譯日期和時間格式,故要讓系統(tǒng)正常工作,至少要提供這些基本的翻譯。
以英語的 .po 文件為基礎(chǔ),翻譯其中的技術(shù)相關(guān)的信息,可能還包括一些使之生效的信息。
技術(shù)相關(guān)的信息ID很容易被認(rèn)出來:它們都是大寫的。 這些信息ID的翻譯與其他信息不同:你需要提供其對應(yīng)的本地化內(nèi)容。 例如,對于 DATETIME_FORMAT (或 DATE_FORMAT 、 TIME_FORMAT ),應(yīng)該提供希望在該語言中使用的格式化字符串。 格式被模板標(biāo)簽now用來識別格式字符串。
一旦LocaleMiddleware決定用戶的偏好,它會讓這個偏好作為request.LANGUAGE_CODE對每一個HttpRequest有效。請隨意在你的視圖代碼中讀一讀這個值。 以下是一個簡單的例子:
def hello_world(request): if request.LANGUAGE_CODE == 'de-at': return HttpResponse("You prefer to read Austrian German.") else: return HttpResponse("You prefer to read another language.")
注意,對于靜態(tài)翻譯(無中間件)而言,此語言在settings.LANGUAGE_CODE中,而對于動態(tài)翻譯(中間件),它在request.LANGUAGE_CODE中。
在你自己的項(xiàng)目中使用翻譯
Django使用以下算法尋找翻譯:
以這種方式,你可以創(chuàng)建包含獨(dú)立翻譯的應(yīng)用程序,可以覆蓋項(xiàng)目中的基本翻譯。 或者,你可以創(chuàng)建一個包含幾個應(yīng)用程序的大項(xiàng)目,并將所有需要的翻譯放在一個大的項(xiàng)目信息文件中。 決定權(quán)在你手中。
所有的信息文件庫都是以同樣方式組織的: 它們是:
$APPPATH/locale//LC_MESSAGES/django.(po|mo) $PROJECTPATH/locale/ /LC_MESSAGES/django.(po|mo)
所有在settings文件中 LOCALE_PATHS 中列出的路徑以其列出的順序搜索
$PYTHONPATH/django/conf/locale//LC_MESSAGES/django.(po|mo)
要創(chuàng)建信息文件,也是使用 django-admin.py makemessages.py 工具,和Django信息文件一樣。 需要做的就是進(jìn)入正確的目錄—— conf/locale (在源碼樹的情況下)或者 locale/ (在應(yīng)用程序信息或項(xiàng)目信息的情況下)所在的目錄下。 同樣地,使用 compile-messages.py 生成 gettext 需要使用的二進(jìn)制 django.mo 文件。
您亦可運(yùn)行django-admin.py compilemessages --settings=path.to.settings 來使編譯器處理所有存在于您 LOCALE_PATHS 設(shè)置中的目錄。
應(yīng)用程序信息文件稍微難以發(fā)現(xiàn)——因?yàn)樗鼈冃枰?LocaleMiddle 。如果不使用中間件,Django只會處理Django的信息文件和項(xiàng)目的信息文件。
最后,需要考慮一下翻譯文件的結(jié)構(gòu)。 若應(yīng)用程序要發(fā)放給其他用戶,應(yīng)用到其它項(xiàng)目中,可能需要使用應(yīng)用程序相關(guān)的翻譯。 但是,使用應(yīng)用程序相關(guān)的翻譯和項(xiàng)目翻譯在使用 make-messages 時會產(chǎn)生古怪的問題。它會遍歷當(dāng)前路徑下所有的文件夾,這樣可能會把應(yīng)用消息文件里存在的消息ID重復(fù)放入項(xiàng)目消息文件中。
最容易的解決方法就是將不屬于項(xiàng)目的應(yīng)用程序(因此附帶著本身的翻譯)存儲在項(xiàng)目樹之外。 這樣做的話,項(xiàng)目級的 make-messages 將只會翻譯與項(xiàng)目精確相關(guān)的,而不包括那些獨(dú)立發(fā)布的應(yīng)用程序中的字符串。
聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com