The Django Book

Chapter 18: Internationalization

绗崄鍏珷 鍥介檯鍖

Django was originally developed smack in the middle of the United States (literally; Lawrence, Kansas, is less than 40 miles from the geographic center of the continental United States). Like most open source projects, though, Djangos community grew to include people from all over the globe. As Djangos community became increasingly diverse, internationalization and localization became increasingly important. Since many developers have at best a fuzzy understanding of these terms, well define them briefly.

Django璇炵敓浜庣編鍥斤紝鍜岃澶氬叾浠栫殑寮婧愯蒋浠朵竴鏍凤紝Django绀惧尯鍙戝睍涓緱鍒颁簡鍏ㄧ悆鑼冨洿鐨勬敮鎸併傛墍浠jano绀惧尯鐨勫浗闄呭寲搴旂敤鍙樺緱闈炲父閲嶈銆傜敱浜庡ぇ閲忓紑鍙戣呭鏈珷鍐呭姣旇緝鍥版儜锛屾墍浠ユ垜浠皢璇︾粏浠嬬粛銆

Internationalization refers to the process of designing programs for the potential use of any locale. This includes marking text (like UI elements and error messages) for future translation, abstracting the display of dates and times so that different local standards may be observed, providing support for differing time zones, and generally making sure that the code contains no assumptions about the location if its users. Youll often see internationalization abbreviated I18N (the number 18 refers to the number of letters omitted between the initial I and the terminal N).

鍥介檯鍖栨槸鎸囦负浜嗗湪浠讳綍鍏跺畠鍦板尯浣跨敤璇ヨ蒋浠惰岃繘琛岃璁$殑杩囩▼銆傚畠鍖呮嫭涓轰簡浠ュ悗鐨勭炕璇戣屾爣璁版枃鏈紙姣斿鐢ㄦ埛鐣岄潰鎺т欢鍜岄敊璇俊鎭瓑锛夛紝鎻愬彇鍑烘棩鏈熷拰鏃堕棿鐨勬樉绀轰互淇濊瘉鏄剧ず閬靛惊涓嶅悓鍦板尯鐨勬爣鍑嗭紝涓轰笉鍚屾椂鍖烘彁渚涙敮鎸侊紝骞朵笖鍦ㄤ竴鑸儏鍐典笅纭繚浠g爜涓笉浼氭湁鍏充簬浣跨敤鑰呮墍鍦ㄥ湴鍖虹殑鍋囪銆傛偍鍙互缁忓父鐪嬪埌鍥介檯鍖栬缂╁啓涓衡淚18N鈥(18琛ㄧずInternationlization杩欎釜鍗曡瘝棣栧瓧姣岻鍜岀粨灏惧瓧姣峃涔嬮棿鐨勫瓧姣嶆湁18涓)銆

Localization refers to the process of actually translating an internationalized program for use in a particular locale. Youll sometimes see localization abbreviated as L10N .

鏈湴鍖栨槸鎸囦娇涓涓浗闄呭寲鐨勭▼搴忎负浜嗗湪鏌愪釜鐗瑰畾鍦板尯浣跨敤鑰岃繘琛岀炕璇戠殑杩囩▼銆傛湁鏃讹紝鏈湴鍖栫缉鍐欎负 L10N

Django itself is fully internationalized; all strings are marked for translation, and settings control the display of locale-dependent values like dates and times. Django also ships with over 40 different localization files. If youre not a native English speaker, theres a good chance that Django is already is translated into your primary language.

Django鏈韩鏄畬鍏ㄥ浗闄呭寲鐨勶紱鎵鏈夌殑瀛楃涓插潎琚爣璁颁负闇瑕佺炕璇戯紝鑰屼笖鍦ㄩ夐」涓彲浠ヨ缃尯鍩熼夐」锛堝鏃堕棿鍜屾棩鏈燂級鐨勬樉绀恒侱jango鏄甫鐫40涓笉鍚岀殑鏈湴鍖栨枃浠跺彂琛岀殑銆傚嵆浣挎偍涓嶆槸浠ヨ嫳璇綔涓烘瘝璇殑锛屼篃寰堟湁鍙兘Django宸茬粡琚炕璇戜负鎮ㄧ殑姣嶈浜嗐

The same internationalization framework used for these localizations is available for you to use in your own code and templates.

fprY2M <a href=”http://udwypazvwjcw.com/“>udwypazvwjcw</a>, [url=http://mhsbklajoxee.com/]mhsbklajoxee[/url], [link=http://fxqerwoknbxo.com/]fxqerwoknbxo[/link], http://xodcudwsvrdn.com/

In a nutshell, youll need to add a minimal number of hooks to your Python code and templates. These hooks are called translation strings . They tell Django, This text should be translated into the end users language, if a translation for this text is available in that language.

绠瑕佸湴璇达紝鎮ㄥ彧闇瑕佹坊鍔犲皯閲忕殑hook鍒版偍鐨凱ython浠g爜鍜屾ā鏉夸腑銆傝繖浜沨ook琚О涓衡滅炕璇戝瓧绗︿覆鈥濄傚畠浠憡璇塂jango锛屽鏋滆繖娈垫枃鏈彲浠ヨ缈昏瘧涓虹粓绔敤鎴疯瑷锛岄偅涔堝氨缈昏瘧杩欐鏂囨湰銆

Django takes care of using these hooks to translate Web applications, on the fly, according to users language preferences.

Django鏍规嵁鐢ㄦ埛鐨勮瑷鍋忓ソ鏉ヤ娇鐢ㄨ繖浜沨ook鍘荤炕璇慦eb搴旂敤绋嬪簭銆

Essentially, Django does two things:

鏈川涓婃潵璇达紝Django鍋氳繖涓や欢浜嬫儏锛

  • It lets developers and template authors specify which parts of their applications should be translatable.

  • 鐢卞紑鍙戣呭拰妯℃澘鐨勪綔鑰呮寚瀹氫粬浠殑搴旂敤绋嬪簭鐨勫摢浜涢儴鍒嗘槸闇瑕佽缈昏瘧鐨勩

  • It uses that information to translate Web applications for particular users according to their language preferences.

  • Django鏍规嵁鐢ㄦ埛鐨勮瑷鍋忓ソ鏉ョ炕璇慦eb搴旂敤绋嬪簭銆

Note

澶囨敞:

Djangos translation machinery uses GNU gettext (http://www.gnu.org/software/gettext/) via the standard gettext module that comes with Python.

Django鐨勭炕璇戞満鍒舵槸浣跨敤 GNU gettext (http://www.gnu.org/software/gettext/)锛屽叿浣撲负Python鏍囧噯妯″潡 gettext

If You Dont Need Internationalization:

fksZVS <a href=”http://rcecordqjdnk.com/“>rcecordqjdnk</a>, [url=http://fgdubzaohlee.com/]fgdubzaohlee[/url], [link=http://ppqbuhjowvns.com/]ppqbuhjowvns[/link], http://icuvrrikoewc.com/

Djangos internationalization hooks are enabled by default, which incurs a small bit of overhead. If you dont use internationalization, you should set USE_I18N = False in your settings file. If USE_I18N is set to False , then Django will make some optimizations so as not to load the internationalization machinery.

Django鍥介檯鍖栫殑hook榛樿鏄紑鍚殑锛岃繖鍙兘浼氱粰Django澧炲姞涓鐐圭偣璐熸媴銆傚鏋滄偍涓嶉渶瑕佸浗闄呭寲鏀寔锛岄偅涔堟偍鍙互鍦ㄦ偍鐨勮缃枃浠朵腑璁剧疆 USE_I18N = False 銆傚鏋 USE_I18N 琚涓 False 锛岄偅涔圖jango浼氳繘琛屼竴浜涗紭鍖栵紝鑰屼笉鍔犺浇鍥介檯鍖栨敮鎸佹満鍒躲

Youll probably also want to remove 'django.core.context_processors.i18n' from your TEMPLATE_CONTEXT_PROCESSORS setting.

鎮ㄤ篃鍙互浠庢偍鐨 TEMPLATE_CONTEXT_PROCESSORS 璁剧疆涓Щ闄 'django.core.context_processors.i18n'

Specifying Translation Strings in Python Code

鍦≒ython浠g爜涓寚瀹氱炕璇戝瓧绗︿覆

Translation strings specify This text should be translated. These strings can appear in your Python code and templates. Its your responsibility to mark translatable strings; the system can only translate strings it knows about.

缈昏瘧瀛楃涓叉寚瀹氳繖娈垫枃鏈渶瑕佽缈昏瘧銆傝繖浜涘瓧绗︿覆鍑虹幇鍦ㄦ偍鐨凱ython浠g爜鍜屾ā鏉夸腑銆傛偍闇瑕佸仛鐨勬槸鏍囪鍑鸿繖浜涚炕璇戝瓧绗︿覆锛涜岀郴缁熷彧浼氱炕璇戝嚭瀹冩墍鐭ラ亾鐨勪笢瑗裤

Standard Translation Functions

鏍囧噯鐨勭炕璇戝嚱鏁

Specify a translation string by using the function _() . (Yes, the name of the function is the underscore character.) This function is available globally (i.e., as a built-in language); you dont have to import it.

ocf07R <a href=”http://qpopfudogomm.com/“>qpopfudogomm</a>, [url=http://zlxzyubhhfhd.com/]zlxzyubhhfhd[/url], [link=http://dbedjhghgiph.com/]dbedjhghgiph[/link], http://opgcbbdwditr.com/

In this example, the text "Welcome to my site." is marked as a translation string:

鍦ㄤ笅闈㈣繖涓緥瀛愪腑锛岃繖娈垫枃鏈 "Welcome to my site" 琚爣璁颁负缈昏瘧瀛楃涓诧細

def my_view(request):
    output = _("Welcome to my site.")
    return HttpResponse(output)

The function django.utils.translation.gettext() is identical to _() . This example is identical to the previous one:

鍑芥暟 django.utils.translation.gettext()_() 鏄浉鍚岀殑銆備笅闈㈣繖涓緥瀛愪笌鍓嶄竴涓緥瀛愭病鏈夊尯鍒細

from django.utils.translation import gettext
def my_view(request):
    output = gettext("Welcome to my site.")
    return HttpResponse(output)

Most developers prefer to use _() , as its shorter.

澶у鏁板紑鍙戣呭枩娆娇鐢 _() , 鍥犱负瀹冩瘮杈冪煭灏.

Translation works on computed values. This example is identical to the previous two:

缈昏瘧瀛楃涓插浜庤鍙ュ悓鏍锋湁鏁堛備笅闈㈣繖涓緥瀛愬拰鍓嶉潰涓や釜渚嬪瓙鐩稿悓锛

def my_view(request):
    words = ['Welcome', 'to', 'my', 'site.']
    output = _(' '.join(words))
    return HttpResponse(output)

Translation works on variables. Again, heres an identical example:

缈昏瘧涔熷彲浠ュ鍙橀噺杩涜銆傚悓鏍风殑渚嬪瓙锛

def my_view(request):
    sentence = 'Welcome to my site.'
    output = _(sentence)
    return HttpResponse(output)

(The caveat with using variables or computed values, as in the previous two examples, is that Djangos translation-string-detecting utility, make-messages.py , wont be able to find these strings. More on make-messages later.)

锛堝浠ヤ笂涓や釜渚嬪瓙鎵绀哄湴浣跨敤鍙橀噺鎴栬鍙ワ紝闇瑕佹敞鎰忕殑涓鐐规槸Django鐨勭炕璇戝瓧绗︿覆妫娴嬪伐鍏凤紝 make-messages.py 锛屼笉鑳芥壘鍒拌繖浜涘瓧绗︿覆銆傚湪鍚庨潰鐨勫唴瀹逛腑浼氱户缁璁鸿繖涓棶棰樸傦級

The strings you pass to _() or gettext() can take placeholders, specified with Pythons standard named-string interpolation syntax, for example:

浼犻掔粰 _()gettext() 鐨勫瓧绗︿覆鍙互鎺ュ彈鐢盤ython鏍囧噯瀛楀吀鍨嬪璞$殑鏍煎紡鍖栧瓧绗︿覆琛ㄨ揪寮忔寚瀹氱殑鍗犱綅绗︼紝姣斿锛

def my_view(request, n):
    output = _('%(name)s is my name.') % {'name': n}
    return HttpResponse(output)

This technique lets language-specific translations reorder the placeholder text. For example, an English translation may be "Adrian is my name." , while a Spanish translation may be "Me llamo Adrian." , with the placeholder (the name) placed after the translated text instead of before it.

杩欓」鎶鏈娇寰楃壒瀹氳瑷鐨勮瘧鏂囧彲浠ュ杩欐鏂囨湰杩涜閲嶆柊鎺掑簭銆傛瘮濡傦紝涓娈垫枃鏈殑鑻辫缈昏瘧涓 "Adrian is my name." 锛岃岃タ鐝墮璇炕璇戜负 "Me llamo Adrian." 锛屾鏃讹紝鍗犱綅绗︼紙鍗硁ame锛夊疄鍦ㄨ缈昏瘧鐨勬枃鏈箣鍓嶈屼笉鏄箣鍚庛

For this reason, you should use named-string interpolation (e.g., %(name)s ) instead of positional interpolation (e.g., %s or %d ). If you use positional interpolation, translations wont be able to reorder placeholder text.

姝e洜涓哄姝わ紝鎮ㄥ簲璇ヤ娇鐢ㄥ瓧鍏稿瀷瀵硅薄鐨勬牸寮忓寲瀛楃涓诧紙姣斿锛 %(name)s 锛夛紝鑰屼笉鏄拡瀵逛綅缃殑鏍煎紡鍖栧瓧绗︿覆锛堟瘮濡傦紝 %s%d 锛夈傚鏋滄偍浣跨敤閽堝浣嶇疆鐨勬牸寮忓寲瀛楃涓诧紝缈昏瘧鏈哄埗灏嗘棤娉曢噸鏂板畨鎺掑寘鍚崰浣嶇鐨勬枃鏈

Marking Strings As No-op

鏍囪瀛楃涓蹭负涓嶆搷浣

Use the function django.utils.translation.gettext_noop() to mark a string as a translation string without actually translating it at that moment. Strings thus marked arent translated until the last possible moment.

aqx6dN <a href=”http://ngytacoffksa.com/“>ngytacoffksa</a>, [url=http://frgtlggamlkr.com/]frgtlggamlkr[/url], [link=http://rzddwvkeesje.com/]rzddwvkeesje[/link], http://tsmbjzujsbqn.com/

Use this approach if you have constant strings that should be stored in the original language such as strings in a database but should be translated at the last possible point in time, such as when the string is presented to the user.

浣跨敤杩欑鏂规硶鐨勭幆澧冩槸锛屾湁瀛楃涓插繀椤讳互鍘熷璇█鐨勫舰寮忓瓨鍌紙濡傚偍瀛樺湪鏁版嵁搴撲腑鐨勫瓧绗︿覆锛夎屽湪鏈鍚庨渶瑕佽缈昏瘧鍑烘潵锛屽褰撳叾鍦ㄧ敤鎴峰墠鏄剧ず鍑烘潵鏃躲

Lazy Translation

鎯版х炕璇

Use the function django.utils.translation.gettext_lazy() to translate strings lazily when the value is accessed rather than when the gettext_lazy() function is called.

浣跨敤 django.utils.translation.gettext_lazy() 鍑芥暟锛屼娇寰楀叾涓殑鍊煎彧鏈夊湪璁块棶鏃舵墠浼氳缈昏瘧锛岃屼笉鏄湪 gettext_lazy() 琚皟鐢ㄦ椂缈昏瘧銆

For example, to mark a fieldss help_text attribute as translatable, do the following:

姣斿锛岃鏍囪 help_text 鍒楁槸闇瑕佺炕璇戠殑锛屽彲浠ヨ繖涔堝仛锛

from django.utils.translation import gettext_lazy

class MyThing(models.Model):
    name = models.CharField(help_text=gettext_lazy('This is the help text'))

In this example, gettext_lazy() stores a lazy reference to the string not the actual translation. The translation itself will be done when the string is used in a string context, such as template rendering on the Django admin site.

鍦ㄨ繖涓緥瀛愪腑锛 gettext_lazy() 灏嗗瓧绗︿覆浣滀负鎯版х炕璇戝瓧绗︿覆瀛樺偍锛屾鏃跺苟娌℃湁杩涜缈昏瘧銆傜炕璇戝伐浣滃皢鍦ㄥ瓧绗︿覆鍦ㄥ瓧绗︿覆涓婁笅鏂囦腑琚敤鍒版椂杩涜锛屾瘮濡傚湪Django绠$悊椤甸潰鎻愪氦妯℃澘鏃躲

If you dont like the verbose name gettext_lazy , you can just alias it as _ (underscore), like so:

濡傛灉瑙夊緱 gettext_lazy 澶繃鍐楅暱锛屽彲浠ョ敤 _ 锛堜笅鍒掔嚎锛変綔涓哄埆鍚嶏紝灏卞儚杩欐牱锛

from django.utils.translation import gettext_lazy as _

class MyThing(models.Model):
    name = models.CharField(help_text=_('This is the help text'))

Always use lazy translations in Django models (otherwise they wont be translated correctly on a per-user basis). And its a good idea to add translations for the field names and table names, too. This means writing explicit verbose_name and verbose_name_plural options in the Meta class:

鍦―jango妯″瀷涓渶濂戒竴鐩翠娇鐢ㄦ儼鎬х炕璇戯紙闄ら潪杩欐牱缈昏瘧鐨勭粨鏋滄棤娉曟纭湴鏄剧ず锛夈傚悓鏃讹紝瀵逛簬鍒楀悕鍜岃〃鍚嶆渶濂戒篃鑳借繘琛岀炕璇戙傝繖闇瑕佸湪 Meta 涓槑纭 verbose_nameverbose_name_plural 鐨勫硷細

from django.utils.translation import gettext_lazy as _

class MyThing(models.Model):
    name = models.CharField(_('name'), help_text=_('This is the help text'))
    class Meta:
        verbose_name = _('my thing')
        verbose_name_plural = _('mythings')

Pluralization

澶嶆暟鐨勫鐞

Use the function django.utils.translation.ngettext() to specify messages that have different singular and plural forms, for example:

浣跨敤 django.utils.translation.ngettext() 鍑芥暟鏉ユ寚瀹氭湁鍗曟暟鍜屽鏁板舰寮忎箣鍒嗙殑淇℃伅锛屾瘮濡傦細

from django.utils.translation import ngettext
def hello_world(request, count):
    page = ngettext(
        'there is %(count)d object',
        'there are %(count)d objects', count
    ) % {'count': count}
    return HttpResponse(page)

ngettext takes three arguments: the singular translation string, the plural translation string, and the number of objects (which is passed to the translation languages as the count variable).

ngettext 鍑芥暟鍖呮嫭涓変釜鍙傛暟锛氬崟鏁板舰寮忕殑缈昏瘧瀛楃涓诧紝澶嶆暟褰㈠紡鐨勭炕璇戝瓧绗︿覆锛屽拰瀵硅薄鐨勪釜鏁帮紙灏嗕互 count 鍙橀噺浼犻掔粰闇瑕佺炕璇戠殑璇█锛夈

Specifying Translation Strings in Template Code

7jEPL5 <a href=”http://siswbqyeiacu.com/“>siswbqyeiacu</a>, [url=http://wggfxnxdjnmc.com/]wggfxnxdjnmc[/url], [link=http://smzrnicwasqa.com/]smzrnicwasqa[/link], http://xqxscmgtbhpc.com/

Using translations in Django templates uses two template tags and a slightly different syntax than in Python code. To give your template access to these tags, put {% load i18n %} toward the top of your template.

Django妯℃澘浣跨敤涓ょ妯℃澘鏍囩锛屼笖璇硶鏍煎紡涓嶱ython浠g爜鏈変簺璁镐笉鍚屻備负浜嗕娇寰楁ā鏉胯闂埌鏍囩锛岄渶瑕佸皢 {% load i18n %} 鏀惧湪妯℃澘鏈鍓嶉潰銆

The {% trans %} template tag marks a string for translations:

{% trans %} 妯℃澘鏍囩鏍囪闇瑕佺炕璇戠殑瀛楃涓诧細

<title>{% trans "This is the title." %}</title>

If you only want to mark a value for translation, but translate it later, use the noop option:

濡傛灉鍙渶瑕佹爣璁板瓧绗︿覆鑰屼互鍚庡啀缈昏瘧锛屽彲浠ヤ娇鐢 noop 閫夐」锛

<title>{% trans "value" noop %}</title>

Its not possible to use template variables in {% trans %} only constant strings, in single or double quotes, are allowed. If your translations require variables (placeholders), use {% blocktrans %} , for example:

{% trans %} 涓笉鍏佽浣跨敤妯℃澘涓殑鍙橀噺锛屽彧鑳戒娇鐢ㄥ崟寮曞彿鎴栧弻寮曞彿涓殑瀛楃涓层傚鏋滅炕璇戞椂闇瑕佺敤鍒板彉閲忥紙鍗犱綅绗︼級锛屽彲浠ヤ娇鐢 {% blocktrans %} 锛屾瘮濡傦細

{% blocktrans %}This will have {{ value }} inside.{% endblocktrans %}

To translate a template expression say, using template filters you need to bind the expression to a local variable for use within the translation block:

浣跨敤妯℃澘杩囨护鍣ㄦ潵缈昏瘧涓涓ā鏉胯〃杈惧紡锛岄渶瑕佸湪缈昏瘧鐨勮繖娈垫枃鏈腑灏嗚〃杈惧紡缁戝畾鍒颁竴涓湰鍦板彉閲忎腑锛

{% blocktrans with value|filter as myvar %}
  This will have {{ myvar }} inside.
{% endblocktrans %}

If you need to bind more than one expression inside a blocktrans tag, separate the pieces with and :

qTgtvg <a href=”http://cbniwxkldxuc.com/“>cbniwxkldxuc</a>, [url=http://lelxwibpyhqi.com/]lelxwibpyhqi[/url], [link=http://climlfoemmpl.com/]climlfoemmpl[/link], http://mmxmuaxedeha.com/

{% blocktrans with book|title as book_t and author|title as author_t %}
  This is {{ book_t }} by {{ author_t }}
{% endblocktrans %}

To pluralize, specify both the singular and plural forms with the {% plural %} tag, which appears within {% blocktrans %} and {% endblocktrans %} , for example:

涓轰簡琛ㄧず鍗曞鏁扮浉鍏崇殑鍐呭锛岄渶瑕佸湪 {% blocktrans %}{% endblocktrans %} 涔嬮棿浣跨敤 {% plural %} 鏍囩鏉ユ寚瀹氬崟澶嶆暟褰㈠紡锛屼緥濡傦細

{% blocktrans count list|length as counter %}
  There is only one {{ name }} object.
{% plural %}
  There are {{ counter }} {{ name }} objects.
{% endblocktrans %}

Internally, all block and inline translations use the appropriate gettext /ngettext call.

鍏跺唴鍦ㄦ満鍒舵槸锛屾墍鏈夌殑鍧楀拰鍐呭祵缈昏瘧璋冪敤鐩稿簲鐨 gettextngettext

When you use RequestContext (see Chapter 10), your templates have access to three translation-specific variables:

浣跨敤 RequestContext 锛堣绗10绔狅級鏃讹紝妯℃澘鍙互璁块棶涓変釜閽堝缈昏瘧鐨勫彉閲忥細

  • {{ LANGUAGES }} is a list of tuples in which the first element is the language code and the second is the language name (in that language).

  • {{ LANGUAGES }} 鏄竴绯诲垪鍏冪粍缁勬垚鐨勫垪琛紝姣忎釜鍏冪粍鐨勭涓涓厓绱犳槸璇█浠g爜锛岀浜屼釜鍏冪礌鏄敤璇ヨ瑷琛ㄧず鐨勮瑷鍚嶇О銆

  • {{ LANGUAGE_CODE }} is the current users preferred language, as a string (e.g., en-us ). (See the How Django Discovers Language Preference section for more information.)

  • {{ LANGUAGE_CODE }} 鏄互瀛楃涓茶〃绀虹殑褰撳墠鐢ㄦ埛鍋忓ソ璇█锛堜緥濡傦紝 en-us 锛夈傦紙璇﹁ Django 濡備綍纭畾璇█鍋忓ソ銆傦級

  • {{ LANGUAGE_BIDI }} is the current languages writing system. If True , its a right-to-left language (e.g., Hebrew, Arabic). If False , its a left-to-right language (e.g., English, French, German).

  • {{ LANGUAGE_BIDI }} 鏄綋鍓嶈瑷鐨勪功鍐欐柟寮忋傝嫢璁句负 True 锛屽垯璇ヨ瑷涔﹀啓鏂瑰悜涓轰粠鍙冲埌宸︼紙濡傚笇浼潵璇拰闃挎媺浼锛夛紱鑻ヨ涓 False 锛屽垯璇ヨ瑷涔﹀啓鏂瑰悜涓轰粠宸﹀埌鍙筹紙濡傝嫳璇佹硶璇拰寰疯锛夈

You can also load these values using template tags:

浣犱篃鍙互閫氳繃浣跨敤妯℃澘鏍囩鏉ュ姞杞借繖浜涘彉閲忥細

{% load i18n %}
{% get_current_language as LANGUAGE_CODE %}
{% get_available_languages as LANGUAGES %}
{% get_current_language_bidi as LANGUAGE_BIDI %}

Translation hooks are also available within any template block tag that accepts constant strings. In those cases, just use _() syntax to specify a translation string, for example:

缈昏瘧鐨刪ook鍦ㄤ换浣曟帴鍙楀父閲忓瓧绗︿覆鐨勬ā鏉垮潡鏍囩鍐呬篃鏄彲浠ヤ娇鐢ㄧ殑銆傛鏃讹紝浣跨敤 _() 琛ㄨ揪寮忔潵鎸囧畾缈昏瘧瀛楃涓诧紝渚嬪锛

{% some_special_tag _("Page not found") value|yesno:_("yes,no") %}

In this case, both the tag and the filter will see the already-translated string (i.e., the string is translated before being passed to the tag handler functions), so they dont need to be aware of translations.

OQy5ZT <a href=”http://zicjwleradwz.com/“>zicjwleradwz</a>, [url=http://klbbjyqcrtdt.com/]klbbjyqcrtdt[/url], [link=http://adylkqwpfagm.com/]adylkqwpfagm[/link], http://bghiparjlrvr.com/

Creating Language Files

鍒涘缓璇█鏂囦欢

Once youve tagged your strings for later translation, you need to write (or obtain) the language translations themselves. In this section we explain how that works.

褰撲綘鏍囪浜嗙炕璇戝瓧绗︿覆锛屼綘灏遍渶瑕佸啓鍑猴紙鎴栬幏鍙栧凡鏈夌殑锛夊搴旂殑璇█缈昏瘧淇℃伅銆傚湪杩欎竴鑺備腑鎴戜滑灏嗚В閲婂浣曚娇瀹冭捣浣滅敤銆

Creating Message Files

鍒涘缓淇℃伅鏂囦欢

The first step is to create a message file for a new language. A message file is a plain-text file representing a single language that contains all available translation strings and how they should be represented in the given language. Message files have a .po file extension.

绗竴姝ワ紝灏辨槸涓轰竴绉嶈瑷鍒涘缓涓涓俊鎭枃浠躲備竴涓俊鎭枃浠舵槸鍖呭惈浜嗘煇涓璇█缈昏瘧瀛楃涓插拰瀵硅繖浜涘瓧绗︿覆鐨勭炕璇戠殑涓涓枃鏈枃浠躲備俊鎭枃浠朵互 .po 涓哄悗缂鍚嶃

Django comes with a tool, bin/make-messages.py , that automates the creation and maintenance of these files.

Django涓甫鏈変竴涓伐鍏凤紝 bin/make-messages.py 锛屽畠瀹屾垚浜嗚繖浜涙枃浠剁殑鍒涘缓鍜岀淮鎶ゅ伐浣溿

To create or update a message file, run this command:

杩愯浠ヤ笅鍛戒护鏉ュ垱寤烘垨鏇存柊涓涓俊鎭枃浠讹細

bin/make-messages.py -l de

where de is the language code for the message file you want to create. The language code, in this case, is in locale format. For example, its pt_BR for Brazilian Portuguese and de_AT for Austrian German. Take a look at thelanguage codes in the django/conf/locale/ directory to see which languages are currently supported.

鍏朵腑 de 鏄墍鍒涘缓鐨勪俊鎭枃浠剁殑璇█浠g爜銆傚湪杩欓噷锛岃瑷浠g爜鏄互鏈湴鏍煎紡缁欏嚭鐨勩備緥濡傦紝宸磋タ鍦板尯鐨勮憽钀勭墮璇负 pt_BR 锛屾境澶у埄浜氬湴鍖虹殑寰疯涓 de_AT 銆傚彲鏌ョ湅 django/conf/locale 鐩綍鑾峰彇Django鎵鏀寔鐨勮瑷浠g爜銆

The script should be run from one of three places:

杩欐鑴氭湰搴旇鍦ㄤ笁澶勪箣涓杩愯锛

  • The root django directory (not a Subversion checkout, but the one that is linked to via $PYTHONPATH or is located somewhere on that path)

  • django 鏍圭洰褰曪紙涓嶆槸Subversion妫鍑虹洰褰曪紝鑰屾槸閫氳繃 $PYTHONPATH 閾炬帴鎴栦綅浜庤璺緞鐨勬煇澶勶級

  • The root directory of your Django project

  • Django椤圭洰鏍圭洰褰

  • The root directory of your Django application

  • Django搴旂敤绋嬪簭鏍圭洰褰

The script runs over the entire tree it is run on and pulls out all strings marked for translation. It creates (or updates) a message file in the directory conf/locale . In the de example, the file will be conf/locale/de/LC_MESSAGES/django.po .

璇ヨ剼鏈綔鐢ㄤ簬鎵鍦ㄧ殑鏁翠釜鐩綍鏍戯紝骞朵笖鎶藉彇鎵鏈夎鏍囪鐨勫瓧绗︿覆浠ヨ繘琛岀炕璇戙傚畠鍦 conf/locale 鐩綍涓嬪垱寤猴紙鎴栨洿鏂帮級浜嗕竴涓俊鎭枃浠躲傚湪涓婇潰杩欎釜渚嬪瓙涓紝杩欎釜淇℃伅鏂囦欢鏄 conf/locale/de/LC_MESSAGES/django.po

If run over your project source tree or your application source tree, it will do the same, but the location of the locale directory is locale/LANG/LC_MESSAGES (note the missing conf prefix). The first time you run it on your tree youll need to create the locale directory.

杩愯浜庨」鐩簮鐮佹爲鎴栧簲鐢ㄧ▼搴忔簮鐮佹爲涓嬫椂锛岃鑴氭湰瀹屾垚鍚屾牱鐨勫姛鑳斤紝浣嗘槸姝ゆ椂locale鐩綍鐨勪綅缃负 locale/LANG/LC_MESSAGES 锛堟敞鎰忔病鏈塦`conf``鍓嶇紑锛夈傚湪绗竴娆¤繍琛屾椂闇瑕佸垱寤 locale 鐩綍銆

No gettext?

娌℃湁gettext?

If you dont have the gettext utilities installed, make-messages.py will create empty files. If thats the case, either install the gettext utilities or just copy the English message file (conf/locale/en/LC_MESSAGES/django.po ) and use it as a starting point; its just an empty translation file.

濡傛灉娌℃湁瀹夎 gettext 缁勪欢锛 make-messages.py 灏嗕細鍒涘缓绌虹櫧鏂囦欢銆傝繖绉嶆儏鍐典笅锛屽畨瑁 gettext 缁勪欢鎴栧彧鏄鍒惰嫳璇俊鎭枃浠( conf/locale/en/LC_MESSAGES/django.po )鏉ヤ綔涓轰竴涓捣鐐癸紱鍙槸涓涓┖鐧界殑缈昏瘧淇℃伅鏂囦欢鑰屽凡銆

The format of .po files is straightforward. Each .po file contains a small bit of metadata, such as the translation maintainers contact information, but the bulk of the file is a list of messages simple mappings between translation strings and the actual translated text for the particular language.

.po 鏂囦欢鏍煎紡寰堢洿瑙傘傛瘡涓 .po 鏂囦欢鍖呭惈涓灏忛儴鍒嗙殑鍏冩暟鎹紝姣斿缈昏瘧缁存姢浜哄憳鐨勮仈绯讳俊鎭紝鑰屾枃浠剁殑澶ч儴鍒嗗唴瀹规槸绠鍗曠殑缈昏瘧瀛楃涓插拰瀵瑰簲璇█缈昏瘧缁撴灉鐨勬槧灏勫叧绯荤殑鍒楄〃銆

For example, if your Django application contains a translation string for the text "Welcome to my site." , like so:

涓句釜渚嬪瓙锛屽鏋淒jango搴旂敤绋嬪簭鍖呮嫭涓涓 "Welcome to my site." 鐨勭炕璇戝瓧绗︿覆锛屽儚杩欐牱锛

_("Welcome to my site.")

then make-messages.py will have created a .po file containing the following snippet a message:

make-message.py 灏嗗垱寤轰竴涓寘鍚互涓嬬墖娈电殑 .po 鏂囦欢锛

#: path/to/python/module.py:23
msgid "Welcome to my site."
msgstr ""

A quick explanation is in order:

鎸夐『搴忕畝鍗曡В閲婁竴涓嬶細

  • msgid is the translation string, which appears in the source. Dont change it.

  • msgid 鏄湪婧愭枃浠朵腑鍑虹幇鐨勭炕璇戝瓧绗︿覆銆備笉瑕佸仛鏀瑰姩銆

  • msgstr is where you put the language-specific translation. It starts out empty, so its your responsibility to change it. Make sure you keep the quotes around your translation.

  • msgstr 鏄浉搴旇瑷鐨勭炕璇戠粨鏋溿傚垰鍒涘缓鏃跺畠鍙槸绌哄瓧绗︿覆锛屾鏃跺氨闇瑕佷綘鏉ュ畬鎴愬畠銆傛敞鎰忎笉瑕佷涪鎺夎鍙ュ墠鍚庣殑寮曞彿銆

  • As a convenience, each message includes the file name and line number from which the translation string was gleaned.

  • 鏂逛究璧疯锛屾瘡涓鏉′俊鎭寘鍚簡缈昏瘧瀛楃涓叉墍鍦ㄦ枃浠剁殑鏂囦欢鍚嶅拰琛屾暟銆

Long messages are a special case. The first string directly after msgstr (or msgid ) is an empty string. Then the content itself will be written over the next few lines as one string per line. Those strings are directly concatenated. Dont forget trailing spaces within the strings; otherwise, theyll be tacked together without whitespace!

瀵逛簬姣旇緝闀跨殑淇℃伅涔熸湁鍏跺鐞嗘柟娉曘 msgstr 锛堟垨 msgid 锛夊悗绱ц窡鐫鐨勫瓧绗︿覆涓轰竴涓┖瀛楃涓层傜劧鍚庣湡姝g殑鍐呭鍦ㄥ叾涓嬮潰鐨勫嚑琛屻傝繖浜涘瓧绗︿覆浼氳鐩存帴杩炲湪涓璧枫傚悓鏃讹紝涓嶈蹇樹簡瀛楃涓叉湯灏剧殑绌烘牸锛屽洜涓哄畠浠細涓嶅姞绌烘牸鍦拌繛鍒颁竴璧枫

For example, heres a multiline translation (taken from the Spanish localization that ships with Django):

姣斿锛屼互涓嬫槸涓涓琛岀炕璇戯紙鍙栬嚜闅廌jango鍙戣鐨勮タ鐝墮鏈湴鍖栨枃浠讹級锛

msgid ""
"There's been an error. It's been reported to the site administrators via e-"
"mail and should be fixed shortly. Thanks for your patience."
msgstr ""
"Ha ocurrido un error. Se ha informado a los administradores del sitio "
"mediante correo electrnico y debera arreglarse en breve. Gracias por su "
"paciencia."

Note the trailing spaces.

娉ㄦ剰姣忎竴琛岀粨灏剧殑绌烘牸銆

Mind Your Charset

娉ㄦ剰瀛楃闆

When creating a .po file with your favorite text editor, first edit the charset line (search for "CHARSET" ) and set it to the charset youll be using to edit the content. Generally, UTF-8 should work for most languages, but gettext should handle any charset you throw at it.

褰撲綘浣跨敤鍠滅埍鐨勬枃鏈紪杈戝櫒鍒涘缓 .po 鏂囦欢鏃讹紝棣栧厛璇风紪杈戝瓧绗﹂泦琛岋紙鎼滅储 "CHARSET" 锛夛紝骞跺皢鍏惰涓轰綘灏嗕娇鐢ㄧ殑瀛楃闆嗐備竴鑸鏉ワ紝UTF-8瀵圭粷澶у鏁拌瑷鏈夋晥锛屼笉杩 gettext 浼氬鐞嗕换浣曚綘鎵浣跨敤鐨勫瓧绗﹂泦銆

To reexamine all source code and templates for new translation strings and update all message files for all languages, run this:

鑻ヨ瀵规柊鍒涘缓鐨勭炕璇戝瓧绗︿覆鏍¢獙鎵鏈夌殑婧愪唬鐮佸拰妯℃澘涓紝骞朵笖鏇存柊鎵鏈夎瑷鐨勪俊鎭枃浠讹紝鍙互杩愯浠ヤ笅鍛戒护锛

make-messages.py -a

Compiling Message Files

缂栬瘧淇℃伅鏂囦欢

After you create your message file, and each time you make changes to it, youll need to compile it into a more efficient form, for use by gettext . Do this with the bin/compile-messages.py utility.

鍒涘缓淇℃伅鏂囦欢涔嬪悗锛屾瘡娆″鍏跺仛浜嗕慨鏀癸紝閮介渶瑕佸皢瀹冮噸鏂扮紪璇戞垚涓绉嶆洿鏈夋晥鐜囩殑褰㈠紡锛屼緵 gettext 浣跨敤銆備娇鐢 `` bin/compile-messages.py `` 鏉ュ畬鎴愯繖椤瑰伐浣溿

This tool runs over all available .po files and creates .mo files, which are binary files optimized for use by gettext . In the same directory from which you ran make-messages.py , run compile-messages.py like this:

杩欎釜宸ュ叿浣滅敤浜庢墍鏈夋湁鏁堢殑 .po 鏂囦欢锛屽垱寤轰紭鍖栬繃鐨勪簩杩涘埗 .mo 鏂囦欢渚 gettext 浣跨敤銆傚湪杩愯 make-messages.py 鐨勫悓涓鐩綍涓嬶紝杩愯 compile-messages.py

bin/compile-messages.py

Thats it. Your translations are ready for use.

灏辨槸杩欐牱浜嗐備綘鐨勭炕璇戞垚鏋滃凡缁忓彲浠ヤ娇鐢ㄤ簡銆

How Django Discovers Language Preference

Django濡備綍澶勭悊璇█鍋忓ソ

Once youve prepared your translations or, if you just want to use the translations that are included with Django youll just need to activate translation for your application.

涓鏃︿綘鍑嗗濂戒簡缈昏瘧锛屽鏋滃笇鏈涘湪Django涓娇鐢紝閭d箞鍙渶瑕佹縺娲昏繖浜涚炕璇戝嵆鍙

Behind the scenes, Django has a very flexible model of deciding which language should be used installation-wide, for a particular user, or both.

鍦ㄨ繖浜涘姛鑳借儗鍚庯紝Django鎷ユ湁涓涓伒娲荤殑妯″瀷鏉ョ‘瀹氬湪瀹夎鍜屼娇鐢ㄥ簲鐢ㄧ▼搴忕殑杩囩▼涓夋嫨浣跨敤鐨勮瑷銆

To set an installation-wide language preference, set LANGUAGE_CODE in your settings file. Django uses this language as the default translation the final attempt if no other translator finds a translation.

鑻ヨ鍦ㄦ暣涓畨瑁呭拰浣跨敤杩囩▼涓‘瀹氳瑷鍋忓ソ锛屽氨瑕佸湪璁剧疆鏂囦欢涓缃 LANGUAGE_CODE 銆侱jango灏嗙敤鎸囧畾鐨勮瑷鏉ヨ繘琛岀炕璇戯紝濡傛灉娌℃湁鍏跺畠鐨勭炕璇戝櫒鍙戠幇瑕佽繘琛岀炕璇戠殑璇彞锛岃繖灏辨槸鏈鍚庝竴姝ヤ簡銆

If all you want to do is run Django with your native language, and a language file is available for your language, simply set LANGUAGE_CODE .

濡傛灉浣犲彧鏄兂瑕佺敤鏈湴璇█鏉ヨ繍琛孌jango锛屽苟涓旇璇█鐨勮瑷鏂囦欢瀛樺湪锛屽彧闇瑕佺畝鍗曞湴璁剧疆 LANGUAGE_CODE 鍗冲彲銆

If you want to let each individual user specify the language he or she prefers, use LocaleMiddleware . LocaleMiddleware enables language selection based on data from the request. It customizes content for each user.

濡傛灉瑕佽姣忎竴涓娇鐢ㄨ呭悇鑷寚瀹氳瑷鍋忓ソ锛屽氨闇瑕佷娇鐢 LocaleMiddlewareLocaleMiddleware 浣垮緱Django鍩轰簬璇锋眰鐨勬暟鎹繘琛岃瑷閫夋嫨锛屼粠鑰屼负姣忎竴浣嶇敤鎴峰畾鍒跺唴瀹广

To use LocaleMiddleware , add 'django.middleware.locale.LocaleMiddleware' to your MIDDLEWARE_CLASSES setting. Because middleware order matters, you should follow these guidelines:

浣跨敤 LocaleMiddleware 闇瑕佸湪 MIDDLEWARE_CLASSES 璁剧疆涓鍔 'django.middleware.locale.LocaleMiddleware' 銆備腑闂翠欢鐨勯『搴忔槸鏈夊奖鍝嶇殑锛屾渶濂芥寜鐓т緷鐓т互涓嬭姹傦細

  • Make sure its among the first middleware classes installed.

  • 淇濊瘉瀹冩槸绗竴鎵瑰畨瑁呯殑涓棿浠剁被銆

  • It should come after SessionMiddleware , because LocaleMiddleware makes use of session data.

  • 鍥犱负 LocalMiddleware 瑕佺敤鍒皊ession鏁版嵁锛屾墍浠ラ渶瑕佹斁鍦 SessionMiddleware 涔嬪悗銆

  • If you use CacheMiddleware , put LocaleMiddleware after it (otherwise users could get cached content from the wrong locale).

  • 濡傛灉浣跨敤浜 CacheMiddleware 锛屽皢 LocaleMiddleware 鏀惧湪 CacheMiddleware 涔嬪悗锛堝惁鍒欑敤鎴峰彲鑳戒細浠庨敊璇殑鏈湴鍖栨枃浠朵腑鍙栧緱缂撳啿鏁版嵁锛夈

For example, your MIDDLEWARE_CLASSES might look like this:

渚嬪锛 MIDDLE_CLASSES 鍙兘浼氭槸濡傛锛

MIDDLEWARE_CLASSES = (
   'django.middleware.common.CommonMiddleware',
   'django.contrib.sessions.middleware.SessionMiddleware',
   'django.middleware.locale.LocaleMiddleware'
)

LocaleMiddleware tries to determine the users language preference by following this algorithm:

LocaleMiddleware 鎸夌収濡備笅绠楁硶纭畾鐢ㄦ埛鐨勮瑷:

  • First, it looks for a django_language key in the current users session.

  • 棣栧厛锛屽湪褰撳墠鐢ㄦ埛 session 鐨勪腑鏌ユ壘閿 django_language 鐨勫硷紱

  • Failing that, it looks for a cookie called django_language .

  • 濡傛灉澶辫触鐨勮瘽锛屾帴鐫鏌ユ壘鍚嶄负 django_language 鐨 cookie 锛

  • Failing that, it looks at the Accept-Language HTTP header. This header is sent by your browser and tells the server which language(s) you prefer, in order of priority. Django tries each language in the header until it finds one with available translations.

  • 杩樻槸澶辫触鐨勮瘽锛屽氨鍦 HTTP 璇锋眰澶撮儴鏌ユ壘 Accept-Language 鍏抽敭瀛楃殑鍊硷紝璇ュ叧閿瓧鏄綘鐨勬祻瑙堝櫒鍙戦佺殑锛屾寜浼樺厛椤哄簭鍛婅瘔鏈嶅姟鍣ㄤ綘鐨勮瑷鍋忓ソ銆侱jango 浼氭牴鎹繖浜涜瑷鐨勯『搴忛愪竴鎼滅储鐩村埌鍙戠幇鍙敤鐨勭炕璇戯紱

  • Failing that, it uses the global LANGUAGE_CODE setting.

  • 浠ヤ笂閮藉け璐ヤ簡鐨勮瘽, 灏变娇鐢ㄥ叏灞鐨 LANGUAGE_CODE 璁惧畾鍊笺

In each of these places, the language preference is expected to be in the standard language format, as a string. For example, Brazilian Portuguese is pt-br . If a base language is available but the sub-language specified is not, Django uses the base language. For example, if a user specifies de-at (Austrian German) but Django only has de available, Django uses de .

鍦ㄤ笂杩版瘡涓澶勶紝璇█鍋忓ソ搴斾綔涓哄瓧绗︿覆锛屼互鏍囧噯鐨勮瑷鏍煎紡鍑虹幇銆傛瘮濡傦紝宸磋タ鍦板尯鐨勮憽钀勭墮璇〃绀轰负 pt-br 銆傚鏋淒jango涓彧鏈夊熀鏈瑷鑰屾病鏈夊叾琛嶇敓鐨勫瓧璇█鐨勮瘽锛孌jango灏嗗彧鏄敤鍩烘湰璇█銆傛瘮濡傦紝濡傛灉鐢ㄦ埛鎸囧畾浜 de-at 锛堟境寮忓痉璇級浣咲jango鍙湁閽堝 de 鐨勭炕璇戯紝閭d箞 de 浼氳閫夌敤銆

Only languages listed in the LANGUAGES setting can be selected. If you want to restrict the language selection to a subset of provided languages (because your application doesnt provide all those languages), set your LANGUAGES setting to a list of languages, for example:

鍙湁鍦 LANGUAGES 璁剧疆涓垪鍑虹殑璇█鎵嶈兘琚夌敤銆傝嫢甯屾湜灏嗚瑷闄愬埗涓烘墍鎻愪緵璇█涓殑鏌愪簺锛堝洜涓哄簲鐢ㄧ▼搴忓苟涓嶆彁渚涙墍鏈夎瑷鐨勮〃绀猴級锛屽垯灏 LANGUAGES 璁剧疆涓烘墍甯屾湜鎻愪緵璇█鐨勫垪琛紝渚嬪锛

LANGUAGES = (
    ('de', _('German')),
    ('en', _('English')),
)

This example restricts languages that are available for automatic selection to German and English (and any sub-language, like de-ch or en-us ).

涓婇潰杩欎釜渚嬪瓙闄愬埗浜嗚瑷鍋忓ソ鍙兘鏄痉璇拰鑻辫锛堝寘鎷畠浠殑瀛愯瑷锛屽 de-chen-us 锛夈

If you define a custom LANGUAGES , its OK to mark the languages as translation strings but use a dummy gettext() function, not the one in django.utils.translation . You should never import django.utils.translation from within your settings file, because that module itself depends on the settings, and that would cause a circular import.

濡傛灉鑷畾涔変簡 LANGUAGES 锛屽皢璇█鏍囪涓虹炕璇戝瓧绗︿覆鏄彲浠ョ殑锛屼絾鏄紝璇蜂笉瑕佷娇鐢 django.utils.translation 涓殑 gettext() 锛堝喅涓嶈鍦╯ettings鏂囦欢涓鍏 django.utils.translation 锛屽洜涓鸿繖涓ā鍧楁湰韬槸渚濊禆浜巗ettings锛岃繖鏍峰仛浼氬鑷存棤闄愬惊鐜級锛岃屾槸浣跨敤涓涓滆櫄鏋勭殑鈥 gettext()

The solution is to use a dummy gettext() function. Heres a sample settings file:

瑙e喅鏂规灏辨槸浣跨敤涓涓滆櫄鍋囩殑鈥 gettext() 銆備互涓嬫槸涓涓猻ettings鏂囦欢鐨勪緥瀛愶細

_ = lambda s: s

LANGUAGES = (
      ('de', _('German')),
      ('en', _('English')),
)

With this arrangement, make-messages.py will still find and mark these strings for translation, but the translation wont happen at runtime, so youll have to remember to wrap the languages in the real gettext() in any code that uses LANGUAGES at runtime.

杩欐牱鍋氱殑璇濓紝 make-messages.py 浠嶄細瀵绘壘骞舵爣璁板嚭灏嗚琚炕璇戠殑杩欎簺瀛楃涓诧紝浣嗙炕璇戜笉浼氬啀杩愯鏃惰繘琛岋紝鏁呰岄渶瑕佸湪浠讳綍浣跨敤 LANGUAGES 鐨勪唬鐮佷腑鐢ㄢ滅湡瀹炵殑鈥 gettext() 鏉ヤ慨楗拌繖浜涜瑷銆

The LocaleMiddleware can only select languages for which there is a Django-provided base translation. If you want to provide translations for your application that arent already in the set of translations in Djangos source tree, youll want to provide at least basic translations for that language. For example, Django uses technical message IDs to translate date formats and time formats so you will need at least those translations for the system to work correctly.

LocaleMiddleware 鍙兘閫夋嫨閭d簺Django宸茬粡鎻愪緵浜嗗熀纭缈昏瘧鐨勮瑷銆傚鏋滄兂瑕佸湪搴旂敤绋嬪簭涓Django涓繕娌℃湁鍩虹缈昏瘧鐨勮瑷鎻愪緵缈昏瘧锛岄偅涔堝繀椤昏嚦灏戝厛鎻愪緵璇ヨ瑷鐨勫熀鏈殑缈昏瘧銆備緥濡傦紝Django浣跨敤鐗瑰畾鐨勪俊鎭疘D鏉ョ炕璇戞棩鏈熷拰鏃堕棿鏍煎紡锛屾晠瑕佽绯荤粺姝e父宸ヤ綔锛岃嚦灏戣鎻愪緵杩欎簺鍩烘湰鐨勭炕璇戙

A good starting point is to copy the English .po file and to translate at least the technical messages, and maybe the validator messages, too.

浠ヨ嫳璇殑 .po 鏂囦欢涓哄熀纭锛岀炕璇戝叾涓殑鎶鏈浉鍏崇殑淇℃伅锛屽彲鑳借繕鍖呮嫭涓浜涗娇涔嬬敓鏁堢殑淇℃伅銆傝繖浼氭槸涓涓ソ鐨勫紑濮嬨

Technical message IDs are easily recognized; theyre all uppercase. You dont translate the message ID as with other messages; rather, you provide the correct local variant on the provided English value. For example, with DATETIME_FORMAT (or DATE_FORMAT or TIME_FORMAT ), this would be the format string that you want to use in your language. The format is identical to the format strings used by the now template tag.

鎶鏈浉鍏崇殑淇℃伅ID寰堝鏄撹浜哄嚭鏉ワ細瀹冧滑閮芥槸澶у啓鐨勩傝繖浜涗俊鎭疘D鐨勭炕璇戜笌鍏朵粬淇℃伅涓嶅悓:浣犻渶瑕佹彁渚涘叾瀵瑰簲鐨勬湰鍦板寲鍐呭銆備緥濡傦紝瀵逛簬 DATETIME_FORMAT 锛堟垨 DATE_FORMATTIME_FORMAT 锛夛紝搴旇鎻愪緵甯屾湜鍦ㄨ璇█涓娇鐢ㄧ殑鏍煎紡鍖栧瓧绗︿覆銆傛牸寮忓拰 now 妯℃澘鏍囩涓娇鐢ㄧ殑鏍煎紡鍖栧瓧绗︿覆涓鏍枫

Once LocaleMiddleware determines the users preference, it makes this preference available as request.LANGUAGE_CODE for each request object. Feel free to read this value in your view code. Heres a simple example:

涓鏃 LocalMiddleware 纭畾浜嗙敤鎴风殑浣跨敤鍋忓ソ锛屽氨灏嗗叾浠 request.LANGUAGE_CODE 鐨勫舰寮忔彁渚涚粰姣忎釜璇锋眰瀵硅薄銆傚姝わ紝鍦ㄨ鍥句唬鐮佷腑灏卞彲浠ヨ嚜鐢变娇鐢ㄤ簡銆備互涓嬫槸涓涓畝鍗曠殑渚嬪瓙锛

def hello_world(request, count):
    if request.LANGUAGE_CODE == 'de-at':
        return HttpResponse("You prefer to read Austrian German.")
    else:
        return HttpResponse("You prefer to read another language.")

Note that, with static (i.e. without middleware) translation, the language is in settings.LANGUAGE_CODE , while with dynamic (middleware) translation, its in request.LANGUAGE_CODE .

娉ㄦ剰锛岄潤鎬佺炕璇戯紙鍗充笉缁忚繃涓棿浠讹級涓殑璇█璁剧疆鏄湪 settings.LANGUAGE_CODE 涓殑锛岃屽姩鎬佺炕璇戯紙鍗充娇鐢ㄤ簡涓棿浠讹級鐨勮瑷璁剧疆瀹炲湪 request.LANGUAGE_CODE

The set_language Redirect View

set_language閲嶅畾鍚戣鍥

As a convenience, Django comes with a view, django.views.i18n.set_language , that sets a users language preference and redirects back to the previous page.

鏂逛究璧疯锛孌jango鑷甫浜嗕竴涓 django.views.i18n.set_language 瑙嗗浘锛屼綔鐢ㄦ槸璁剧疆鐢ㄦ埛璇█鍋忓ソ骞堕噸瀹氬悜杩斿洖鍒板墠涓椤甸潰銆

Activate this view by adding the following line to your URLconf:

鍦║RLconf涓姞鍏ヤ笅闈㈣繖琛屼唬鐮佹潵婵娲昏繖涓鍥撅細

(r'^i18n/', include('django.conf.urls.i18n')),

(Note that this example makes the view available at /i18n/setlang/ .)

锛堟敞鎰忚繖涓緥瀛愪娇寰楄繖涓鍥惧湪 /i18n/setlang/ 涓湁鏁堛傦級

The view expects to be called via the GET method, with a language parameter set in the query string. If session support is enabled, the view saves the language choice in the users session. Otherwise, it saves the language choice in a django_language cookie.

杩欎釜瑙嗗浘鏄氳繃 GET 鏂规硶璋冪敤鐨勶紝鍦≦uery String涓寘鍚簡 language 鍙傛暟銆傚鏋渟ession宸插惎鐢紝杩欎釜瑙嗗浘浼氬皢璇█閫夋嫨淇濆瓨鍦ㄧ敤鎴风殑session涓傚惁鍒欙紝璇█閫夋嫨灏嗚淇濆瓨鍦ㄥ悕涓 django_language 鐨刢ookie涓

After setting the language choice, Django redirects the user, following this algorithm:

淇濆瓨浜嗚瑷閫夋嫨鍚庯紝Django鏍规嵁浠ヤ笅绠楁硶鏉ラ噸瀹氬悜椤甸潰锛

  • Django looks for a next parameter in the query string.

  • Django鍦ㄦ彁浜ょ殑Query String涓鎵 next 鍙傛暟銆

  • If that doesnt exist or is empty, Django tries the URL in the Referer header.

  • 濡傛灉 next 鍙傛暟涓嶅瓨鍦ㄦ垨涓虹┖锛孌jango灏濊瘯閲嶅畾鍚戦〉闈负HTML澶撮儴淇℃伅涓 Referer 鐨勫笺

  • If thats empty say, if a users browser suppresses that header then the user will be redirected to / (the site root) as a fallback.

  • 濡傛灉 Referer 涔熸槸绌虹殑锛屽嵆璇ョ敤鎴风殑娴忚鍣ㄥ苟涓嶅彂閫 Referer 澶翠俊鎭紝鍒欓〉闈㈠皢閲嶅畾鍚戝埌 / 锛堥〉闈㈡牴鐩綍锛夈

Heres example HTML template code:

杩欐槸涓涓狧TML妯℃澘浠g爜鐨勪緥瀛愶細

<form action="/i18n/setlang/" method="get">
<input name="next" type="hidden" value="/next/page/" />
<select name="language">
{% for lang in LANGUAGES %}
<option value="{{ lang.0 }}">{{ lang.1 }}</option>
{% endfor %}
</select>
<input type="submit" value="Go" />
</form>

Using Translations in Your Own Projects

鍦ㄤ綘鑷繁鐨勯」鐩腑浣跨敤缈昏瘧

Django looks for translations by following this algorithm:

Django浣跨敤浠ヤ笅绠楁硶瀵绘壘缈昏瘧锛

  • First, it looks for a locale directory in the application directory of the view thats being called. If it finds a translation for the selected language, the translation will be installed.

  • 棣栧厛锛孌jango鍦ㄨ瑙嗗浘鎵鍦ㄧ殑搴旂敤绋嬪簭鏂囦欢澶逛腑瀵绘壘 locale 鐩綍銆傝嫢鎵惧埌鎵閫夎瑷鐨勭炕璇戯紝鍒欏姞杞借缈昏瘧銆

  • Next, it looks for a locale directory in the project directory. If it finds a translation, the translation will be installed.

  • 绗簩姝ワ紝Django鍦ㄩ」鐩洰褰曚腑瀵绘壘 locale 鐩綍銆傝嫢鎵惧埌缈昏瘧锛屽垯鍔犺浇璇ョ炕璇戙

  • Finally, it checks the base translation in django/conf/locale .

  • 鏈鍚庯紝Django浣跨敤 django/conf/locale 鐩綍涓殑鍩烘湰缈昏瘧銆

This way, you can write applications that include their own translations, and you can override base translations in your project path. Or, you can just build a big project out of several applications and put all translations into one big project message file. The choice is yours.

浠ヨ繖绉嶆柟寮忥紝浣犲彲浠ュ垱寤哄寘鍚嫭绔嬬炕璇戠殑搴旂敤绋嬪簭锛屽彲浠ヨ鐩栭」鐩腑鐨勫熀鏈炕璇戙傛垨鑰咃紝浣犲彲浠ュ垱寤轰竴涓寘鍚嚑涓簲鐢ㄧ▼搴忕殑澶ч」鐩紝骞跺皢鎵鏈夐渶瑕佺殑缈昏瘧鏀惧湪涓涓ぇ鐨勯」鐩俊鎭枃浠朵腑銆傚喅瀹氭潈鍦ㄤ綘鎵嬩腑銆

Note

娉ㄦ剰

If youre using manually configured settings, the locale directory in the project directory will not be examined, since Django loses the ability to work out the location of the project directory. (Django normally uses the location of the settings file to determine this, and a settings file doesnt exist if youre manually configuring your settings.)

濡傛灉鏄娇鐢ㄦ墜鍔ㄩ厤缃殑settings鏂囦欢锛屽洜Django鏃犳硶鑾峰彇椤圭洰鐩綍鐨勪綅缃紝鎵浠ラ」鐩洰褰曚笅鐨 locale 鐩綍灏嗕笉浼氳妫鏌ャ傦紙Django涓鑸娇鐢╯ettings鏂囦欢鐨勪綅缃潵纭畾椤圭洰鐩綍锛岃岃嫢鎵嬪姩閰嶇疆settings鏂囦欢锛屽垯settings鏂囦欢涓嶄細鍦ㄨ鐩綍涓傦級

All message file repositories are structured the same way:

鎵鏈夌殑淇℃伅鏂囦欢搴撻兘鏄互鍚屾牱鏂瑰紡缁勭粐鐨勶細

  • $APPPATH/locale/<language>/LC_MESSAGES/django.(po|mo)

  • $APPPATH/locale/<language>/LC_MESSAGES/django.(po|mo)

  • $PROJECTPATH/locale/<language>/LC_MESSAGES/django.(po|mo)

  • $PROJECTPATH/locale/<language>/LC_MESSAGES/django.(po|mo)

  • All paths listed in LOCALE_PATHS in your settings file are searched in that order for <language>/LC_MESSAGES/django.(po|mo)

  • 鎵鏈夊湪settings鏂囦欢涓 LOCALE_PATHS 涓垪鍑虹殑璺緞浠ュ叾鍒楀嚭鐨勯『搴忔悳绱 <language>/LC_MESSAGES/django.(po|mo)

  • $PYTHONPATH/django/conf/locale/<language>/LC_MESSAGES/django.(po|mo)

  • $PYTHONPATH/django/conf/locale/<language>/LC_MESSAGES/django.(po|mo)

To create message files, you use the same make-messages.py tool as with the Django message files. You only need to be in the right place in the directory where either the conf/locale (in case of the source tree) or the locale/ (in case of application messages or project messages) directory is located. And you use the same compile-messages.py to produce the binary django.mo files that are used by gettext .

瑕佸垱寤轰俊鎭枃浠讹紝涔熸槸浣跨敤 make-messages.py 宸ュ叿锛屽拰Django淇℃伅鏂囦欢涓鏍枫傞渶瑕佸仛鐨勫氨鏄敼鍙樺埌姝g‘鐨勭洰褰曚笅鈥斺 conf/locale 锛堝湪婧愮爜鏍戠殑鎯呭喌涓嬶級鎴栬 locale/ 锛堝湪搴旂敤绋嬪簭淇℃伅鎴栭」鐩俊鎭殑鎯呭喌涓嬶級鎵鍦ㄧ殑鐩綍涓嬨傚悓鏍峰湴锛屼娇鐢 compile-messages.py 鐢熸垚 gettext 闇瑕佷娇鐢ㄧ殑浜岃繘鍒 django.mo 鏂囦欢銆

Application message files are a bit complicated to discover they need the LocaleMiddleware . If you dont use the middleware, only the Django message files and project message files will be processed.

搴旂敤绋嬪簭淇℃伅鏂囦欢绋嶅井闅句互鍙戠幇鈥斺斿洜涓哄畠浠渶瑕 LocaleMiddle 銆傚鏋滀笉浣跨敤涓棿浠讹紝Django鍙細澶勭悊Django鐨勪俊鎭枃浠跺拰椤圭洰鐨勪俊鎭枃浠躲

Finally, you should give some thought to the structure of your translation files. If your applications need to be delivered to other users and will be used in other projects, you might want to use application-specific translations. But using application-specific translations and project translations could produce weird problems with make-messages . make-messages will traverse all directories below the current path and so might put message IDs into the project message file that are already in application message files.

鏈鍚庯紝闇瑕佽冭檻涓涓嬬炕璇戞枃浠剁殑缁撴瀯銆傝嫢搴旂敤绋嬪簭瑕佸彂鏀剧粰鍏朵粬鐢ㄦ埛锛屽簲鐢ㄥ埌鍏跺畠椤圭洰涓紝鍙兘闇瑕佷娇鐢ㄥ簲鐢ㄧ▼搴忕浉鍏崇殑缈昏瘧銆備絾鏄紝浣跨敤搴旂敤绋嬪簭鐩稿叧鐨勭炕璇戝拰椤圭洰缈昏瘧鍦ㄤ娇鐢 make-messages 鏃朵細浜х敓鍙ゆ殑闂銆 make-messages 浼氶亶鍘嗗綋鍓嶈矾寰勪笅鐨勬墍鏈夌洰褰曪紝鎵浠ュ彲鑳戒細灏嗗簲鐢ㄧ▼搴忎俊鎭枃浠跺凡鏈夌殑淇℃伅ID鏀惧湪椤圭洰淇℃伅鏂囦欢涓

The easiest way out is to store applications that are not part of the project (and so carry their own translations) outside the project tree. That way, make-messages on the project level will only translate strings that are connected to your explicit project and not strings that are distributed independently.

鏈瀹规槗鐨勮В鍐虫柟娉曞氨鏄皢涓嶅睘浜庨」鐩殑搴旂敤绋嬪簭锛堝洜姝ら檮甯︾潃鏈韩鐨勭炕璇戯級瀛樺偍鍦ㄩ」鐩爲涔嬪銆傝繖鏍峰仛鐨勮瘽锛岄」鐩骇鐨 make-messages 灏嗗彧浼氱炕璇戜笌椤圭洰绮剧‘鐩稿叧鐨勶紝鑰屼笉鍖呮嫭閭d簺鐙珛鍙戝竷鐨勫簲鐢ㄧ▼搴忎腑鐨勫瓧绗︿覆銆

Translations and JavaScript

缈昏瘧涓嶫avaScript

Adding translations to JavaScript poses some problems:

灏嗙炕璇戞坊鍔犲埌JavaScript浼氬紩璧蜂竴浜涢棶棰橈細

  • JavaScript code doesnt have access to a gettext implementation.

  • JavaScript浠g爜鏃犳硶璁块棶涓涓 gettext 鐨勫疄鐜般

  • JavaScript code doesnt have access to .po or .mo files; they need to be delivered by the server.

  • JavaScript浠g爜鏃犳硶璁块棶 .po.mo 鏂囦欢锛屽畠浠渶瑕佺敱鏈嶅姟鍣ㄥ垎鍙戙

  • The translation catalogs for JavaScript should be kept as small as possible.

  • 閽堝JavaScript鐨勭炕璇戠洰褰曞簲灏介噺灏忋

Django provides an integrated solution for these problems: it passes the translations into JavaScript, so you can call gettext and friends from within JavaScript.

Django宸茬粡鎻愪緵浜嗕竴涓泦鎴愯В鍐虫柟妗堬細瀹冧細灏嗙炕璇戜紶閫掔粰JavaScript锛屽洜姝ゅ氨鍙互鍦↗avaScript涓皟鐢 gettext 涔嬬被鐨勪唬鐮併

The javascript_catalog View

javascript_catalog瑙嗗浘

The main solution to these problems is the javascript_catalog view, which generates a JavaScript code library with functions that mimic the gettext interface, plus an array of translation strings. Those translation strings are taken from the application, project, or Django core, according to what you specify in either the info_dict or the URL.

杩欎簺闂鐨勪富瑕佽В鍐虫柟妗堝氨鏄 javascript_catalog 瑙嗗浘銆傝瑙嗗浘鐢熸垚涓涓狫avaScript浠g爜搴擄紝鍖呮嫭妯′豢 gettext 鎺ュ彛鐨勫嚱鏁帮紝鍜岀炕璇戝瓧绗︿覆鐨勬暟缁勩傝繖浜涚炕璇戝瓧绗︿覆鏉ヨ嚜搴旂敤绋嬪簭锛岄」鐩紝鎴栬匘jango鏍稿績锛屽叿浣撶敱 info_dict 鎴朥RL鏉ョ‘瀹氥

You hook it up like this:

鍍忚繖鏍蜂娇鐢細

js_info_dict = {
    'packages': ('your.app.package',),
}

urlpatterns = patterns('',
    (r'^jsi18n/$', 'django.views.i18n.javascript_catalog', js_info_dict),
)

Each string in packages should be in Python dotted-package syntax (the same format as the strings in INSTALLED_APPS ) and should refer to a package that contains a locale directory. If you specify multiple packages, all those catalogs are merged into one catalog. This is useful if youre depending upon JavaScript that uses strings from different applications.

packages 閲岀殑姣忎釜瀛楃涓插簲璇ユ槸Python涓殑鐐瑰垎鍓茬殑鍖呯殑琛ㄨ揪寮忓舰寮忥紙鍜屽湪 INSTALLED_APPS 涓殑瀛楃涓茬浉鍚岀殑鏍煎紡锛夛紝鑰屼笖搴旀寚鍚戝寘鍚 locale 鐩綍鐨勫寘銆傚鏋滄寚瀹氫簡澶氫釜鍖咃紝鎵鏈夌殑鐩綍浼氬悎骞舵垚涓涓洰褰曘傚鏋滄湁鐢ㄥ埌鏉ヨ嚜涓嶅悓搴旂敤绋嬪簭鐨勫瓧绗︿覆鐨凧avaScript锛岃繖绉嶆満鍒朵細寰堟湁甯姪銆

You can make the view dynamic by putting the packages into the URL pattern:

浣犲彲浠ュ姩鎬佷娇鐢ㄨ鍥撅紝灏嗗寘鏀惧湪urlpatterns閲岋細

urlpatterns = patterns('',
    (r'^jsi18n/(?P<packages>\S+?)/$, 'django.views.i18n.javascript_catalog'),
)

With this, you specify the packages as a list of package names delimited by plus signs (+ ) in the URL. This is especially useful if your pages use code from different applications, and this changes often and you dont want to pull in one big catalog file. As a security measure, these values can only be either django.conf or any package from the INSTALLED_APPS setting.

杩欐牱鐨勮瘽锛屽氨鍙互鍦║RL涓寚瀹氱敱鍔犲彿锛 + 锛夊垎闅斿寘鍚嶇殑鍖呬簡銆傚鏋滈〉闈娇鐢ㄦ潵鑷笉鍚屽簲鐢ㄧ▼搴忕殑浠g爜锛屼笖缁忓父鏀瑰彉锛岃繕涓嶆兂灏嗗叾鏀惧湪涓涓ぇ鐨勭洰褰曟枃浠朵腑锛屽浜庤繖浜涙儏鍐碉紝鏄剧劧杩欐槸寰堟湁鐢ㄧ殑銆傚嚭浜庡畨鍏ㄨ冭檻锛岃繖浜涘煎彧鑳芥槸 django.confINSTALLED_APPS 璁剧疆涓殑鍖呫

Using the JavaScript Translation Catalog

浣跨敤JavaScript缈昏瘧鐩綍

To use the catalog, just pull in the dynamically generated script like this:

瑕佷娇鐢ㄨ繖涓洰褰曪紝鍙杩欐牱寮曞叆鍔ㄦ佺敓鎴愮殑鑴氭湰锛

<script type="text/javascript" src="/path/to/jsi18n/"></script>

This is how the admin site fetches the translation catalog from the server. When the catalog is loaded, your JavaScript code can use the standard gettext interface to access it:

杩欏氨鏄鐞嗛〉闈㈠浣曚粠鏈嶅姟鍣ㄨ幏鍙栫炕璇戠洰褰曘傚綋鐩綍鍔犺浇鍚庯紝JavaScript浠g爜灏辫兘閫氳繃鏍囧噯鐨 gettext 鎺ュ彛杩涜璁块棶锛

document.write(gettext('this is to be translated'));

There even is a ngettext interface and a string interpolation function:

鐢氳嚦鏈変竴涓 ngettext 鎺ュ彛鍜屼竴涓瓧绗︿覆鏌ヨˉ鍑芥暟锛

d = {
    count: 10
};
s = interpolate(ngettext('this is %(count)s object', 'this are %(count)s objects', d.count), d);

The interpolate function supports both positional interpolation and named interpolation. So the preceding code could have been written as follows:

interpolate 鍑芥暟鏀寔浣嶇疆鎻掕ˉ鍜屽悕瀛楁煡琛ャ傚洜姝ゅ墠闈㈢殑浠g爜涔熷彲浠ュ啓鎴愯繖鏍凤細

s = interpolate(ngettext('this is %s object', 'this are %s objects', 11), [11]);

The interpolation syntax is borrowed from Python. You shouldnt go over the top with string interpolation, though this is still JavaScript, so the code will have to do repeated regular-expression substitutions. This isnt as fast as string interpolation in Python, so keep it to those cases where you really need it (e.g., in conjunction with ngettext to produce proper pluralization).

鎻掕ˉ鐨勮娉曟槸鍊熼壌浜哖ython銆備絾涓嶅簲璇ヨ秴杩囧瓧绗︿覆鎻掕ˉ鐨勮兘鍔涳紝杩欎粛鐒惰繕鏄疛avaScript锛屽洜姝や唬鐮佸皢涓嶅緱涓嶅仛閲嶅鐨勬鍒欐浛鎹€傚畠涓嶄細鍜孭ython涓殑瀛楃涓叉彃琛ヤ竴鏍峰揩锛屽洜姝ゅ彧鏈夌湡姝i渶瑕佺殑鏃跺欏啀浣跨敤瀹冿紙渚嬪锛屽埄鐢 ngettext 鐢熸垚鍚堥傜殑澶嶆暟褰㈠紡锛夈

Creating JavaScript Translation Catalogs

鍒涘缓JavaScript缈昏瘧鐩綍

You create and update the translation catalogs the same way as the other Django translation catalogs: with the `make-messages.py` tool. The only difference is you need to provide a -d djangojs parameter, like this:

鐢ㄥ拰鍏跺畠Django缈昏瘧鐩綍鐩稿悓鐨勬柟娉曟潵鍒涘缓鍜屾洿鏂癑avaScript缈昏瘧鐩綍锛氱敤 `make-messages.py` 宸ュ叿銆傚敮涓鐨勫樊鍒槸闇瑕佹彁渚涗竴涓 -d djangojs 鐨勫弬鏁帮紝灏卞儚杩欐牱锛

make-messages.py -d djangojs -l de

This creates or updates the translation catalog for JavaScript for German. After updating translation catalogs, just run compile-messages.py the same way as you do with normal Django translation catalogs.

杩欐牱鏉ュ垱寤烘垨鏇存柊JavaScript鐨勫痉璇炕璇戠洰褰曘傚拰鏅氱殑Django缈昏瘧鐩綍涓鏍凤紝鏇存柊浜嗙炕璇戠洰褰曞悗锛岃繍琛 compile-messages.py 鍗冲彲銆

Notes for Users Familiar with gettext

鐔熸倝 gettext 鐢ㄦ埛鐨勬敞鎰忎簨椤

If you know gettext , you might note these special things in the way Django does translation:

濡傛灉浣犱簡瑙 gettext 锛屼綘鍙兘浼氬彂鐜癉jango杩涜缈昏瘧鏃剁殑涓浜涚壒娈婄殑涓滆タ锛

  • The string domain is django or djangojs . The string domain is used to differentiate between different programs that store their data in a common message-file library (usually /usr/share/locale/ ). The django domain is used for Python and template translation strings, and is loaded into the global translation catalogs. The djangojs domain is only used for JavaScript translation catalogs to make sure that those are as small as possible.

  • 瀛楃涓插煙涓 djangodjangojs 銆傚瓧绗︿覆鍩熸槸鐢ㄦ潵鍖哄埆灏嗘暟鎹瓨鍌ㄥ湪鍚屼竴淇℃伅鏂囦欢搴擄紙涓鑸槸 /usr/share/locale/ 锛夌殑涓嶅悓绋嬪簭銆 django 鍩熸槸涓篜ython鍜屾ā鏉跨炕璇戝瓧绗︿覆鏈嶅姟鐨勶紝琚姞杞藉埌鍏ㄥ眬缈昏瘧鐩綍銆 djangojs 鍩熺敤鍦↗avaScript缈昏瘧鐩綍涓紝浠ョ‘淇濆叾瓒冲灏忋

  • Django only uses gettext and gettext_noop . Thats because Django always uses DEFAULT_CHARSET strings internally. There isnt much benefit to using ugettext , because youll always need to produce UTF-8 anyway.

  • Django浠呴傜敤 gettextgettext_noop 銆傝繖鏄洜涓篋jango鎬绘槸鍐呭湪鍦颁娇鐢 DEFAULT_CHARSET 瀛楃涓层備娇鐢 ugettext 骞舵病鏈変粈涔堝ソ澶勶紝鍥犱负鎬绘槸闇瑕佺敓鎴怳TF-8銆

  • Django doesnt use xgettext alone. It uses Python wrappers around xgettext and msgfmt . Thats mostly for convenience.

  • Django涓嶅崟鐙娇鐢 xgettext 锛岃屾槸缁忚繃Python鍖呰鍚庣殑 xgettextmsgfmt 銆傝繖涓昏鏄负浜嗘柟渚裤

Whats Next?

涓嬩竴绔

This chapter mostly concludes our coverage of Djangos features. You should now know enough to start producing your own Django sites.

杩欎竴绔犲熀鏈笂宸茬粡缁撴潫浜嗘垜浠浜嶥jango鐗规х殑浠嬬粛銆備綘搴旇宸茬粡鎺屾彙浜嗗垱寤轰綘鑷繁Django椤甸潰鐨勭煡璇嗐

However, writing the code is only the first step in deploying a successful Web site. The next two chapters cover the things youll need to know if you want your site to survive in the real world. Chapter 19 discuses how you can secure your sites and your users from malicious attackers, and Chapter 20 details how to deploy a Django application onto one or many servers.

鐒惰岋紝缂栫爜宸ヤ綔浠呬粎鏄儴缃蹭竴涓垚鍔熺綉绔欑殑绗竴姝ャ傛帴涓嬫潵鐨勪袱绔犲寘鎷簡浣犵殑缃戠珯鍦ㄧ綉缁滀笘鐣岀殑鐢熷瓨涔嬮亾銆傜19绔犺璁轰簡濡備綍闃茶寖鎭舵剰鏀诲嚮锛屼互澧炲己绔欑偣鐨勫畨鍏ㄦэ紝淇濇姢浣跨敤鑰呯殑瀹夊叏锛涚20绔犺杩颁簡濡備綍灏嗕竴涓狣jango搴旂敤绋嬪簭閮ㄧ讲鍒颁竴涓垨澶氫釜鏈嶅姟鍣ㄤ笂銆

Copyright 2006 Adrian Holovaty and Jacob Kaplan-Moss.
This work is licensed under the GNU Free Document License.
Hosting graciously provided by media temple
Chinese translate hosting by py3k.cn.