Using settings.LANGUAGES with properly translated

2020-07-13 09:15发布

问题:

From Django Documentation:

If you define a custom LANGUAGES setting, it's OK to mark the languages as translation strings (as in the default value displayed above) -- 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 in itself depends on the settings, and that would cause a circular import. The solution is to use a "dummy" gettext() function. Here's a sample settings file:

gettext = lambda s: s LANGUAGES = ( ('de', gettext('German')), ('en', gettext('English')), )

With this arrangement, django-admin.py makemessages will still find and mark these strings for translation, but the translation won't happen at runtime -- so you'll have to remember to wrap the languages in the real gettext() in any code that uses LANGUAGES at runtime.

What does it exactly mean to wrap languages in real gettext()? How it should be called in the code?

回答1:

According to the latest docs you can use ugettext_lazy in settings without causing circular imports:

from django.utils.translation import ugettext_lazy as _

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


回答2:

Exactly what it says: call gettext() on the language names when you actually use them or show them to the user:

from django.utils.translation import ugettext

for lang_code, lang_name in settings.LANGUAGES:
    translated_name = ugettext(lang_name)
    ...

(You should generally use ugettext rather than gettext, since all text in Django is unicode.)

To do the equivalent in a template, just use the {% blocktrans %} tag, which just calls ugettext behind the scenes:

{% for lang in LANGUAGES %}
  {% blocktrans %}{{ lang.1 }}{% endblocktrans %}
{% endfor %}


回答3:

This is really a comment and further explanation on the above Q&A. I could not get my translations to work, read and re-read the docs, searched for hours online, and after reading this post I realized it came down to this:

I originally had:

LANGUAGES = (
    ('en', 'English'),
    ('nl', 'Dutch'),
    )

Which would not work, then after reading this tried

ugettext = lambda s: s
LANGUAGES = (
    ('en', ugettext('English')),
    ('nl', ugettext('Dutch')),
    )

Which made everything work... and I just searched for this and it is in the doc's at https://docs.djangoproject.com/en/1.4/topics/i18n/translation/#how-django-discovers-language-preference, toward the bottom of this section...



回答4:

in Template you could just do the following:

{% for lang in LANGUAGES %}
      {% trans lang.1 %}
{% endfor %}