【问题标题】:Django switching, for a block of code, switch the language so translations are done in one languageDjango 切换,对于一段代码,切换语言,以便翻译以一种语言完成
【发布时间】:2011-07-12 15:17:34
【问题描述】:

我有一个使用工作进程向用户发送电子邮件的 django 项目。工作进程监听 rabbitmq 服务器并获取有关要发送的电子邮件、模板变量、要发送到的电子邮件地址等的所有详细信息。电子邮件正文是使用 django 模板和render_to_string 创建的。

但是我想将其国际化。我们的一些用户将使用英语网站,一些用户使用其他语言。他们应该收到以他们的语言发送的电子邮件。我已尝试 i18n 电子邮件工作进程(使用 django.utils.translations.ugettext/ugettext_lazy),以便电子邮件主题和电子邮件正文分别具有 _(...) 或 {% blocktrans %}。

但是,由于电子邮件是在不同的后台工作进程中呈现和发送的,因此普通的django language detection process 似乎并不适用。没有用户会话、cookie 或 http 标头可供查看。发送消息到rabbitmq服务器时,我可以存储语言代码

但是我如何告诉 django/gettext 在某一时刻使用该语言。

例如我发送电子邮件的函数可能如下所示:

def send_email(details):
  lang = details['lang']
  name = details['name']
  email_address = details['email_address']

  switch_gettext_to_this_language_what_goes_here(lang):
  # ?????
  email_subject = _("Welcome to $SITE")  

如何将 django 翻译/gettext 切换为特定语言代码,以便 _() 使用该语言代码?

【问题讨论】:

    标签: python django internationalization translation gettext


    【解决方案1】:

    使用django-i18next (https://pypi.python.org/pypi/django-i18next) 非常简单。

    加载模板标签。

    {% load i18n i18next %}
    

    以下代码强制使用荷兰语语言环境来设置 overridelocale 块内的任何内容。

    {% overridelocale 'nl' %}
        <p>
            <a href="/login/">{% trans "Log in" %}</a>
        </p>
    {% endoverridelocale %}
    

    以下代码强制使用俄语语言环境设置 overridelocale 块内的任何内容。

    {% overridelocale 'ru' %}
        <p>
            <a href="/login/">{% trans "Log in" %}</a>
        </p>
    {% endoverridelocale %}
    

    以下代码强制将 overridelocale 块内的任何内容强制为英语语言环境。

    {% overridelocale 'en' %}
        <p>
            <a href="/login/">{% trans "Log in" %}</a>
        </p>
    {% endoverridelocale %}
    

    【讨论】:

    【解决方案2】:

    正如@SteveMayne 在评论中指出的(但值得回答),您现在可以使用上下文管理器translation.override(适用于 Django 1.6,未检查早期版本):

    from django.utils import translation
    print(_("Hello"))  # Will print to Hello if default = 'en'
    
    # Make a block where the language will be Danish
    with translation.override('dk'):
        print(_("Hello"))  # print "Hej"
    

    它基本上使用与@bitrut 答案相同的东西,但它是内置在 Django 中的,所以它减少了依赖...

    【讨论】:

    • 它至少可以追溯到 Django 1.4!
    • override 更安全,因为你做完你的东西后不必考虑设置原始语言!
    【解决方案3】:

    您可以使用上下文管理器以一种很好的方式强制语言:

    class force_lang:
        def __init__(self, new_lang):
            self.new_lang = new_lang
            self.old_lang = translation.get_language()
        def __enter__(self):
           translation.activate(self.new_lang)
        def __exit__(self, type, value, tb):
           translation.activate(self.old_lang)
    

    那么你可以使用with声明:

    with force_lang('en'):
        ...
    

    【讨论】:

    • 现在包含在 translation.override 类中。 with translation.override('en'):
    【解决方案4】:

    切换语言的最简单方法是:

    from django.utils.translation import activate
    activate('en')
    # do smthg
    activate('pl')
    # do something in other language
    

    注意这一点,因为它正在更改此进程/线程的其余执行的上下文。

    【讨论】:

    • 请注意,django.utils.translation 现在有一个 override(lang) 上下文管理器,它将在退出时自动重置原始语言环境。
    【解决方案5】:

    原来是the django docs explain how

    虽然 Django 提供了一组丰富的 i18n 工具用于视图和模板,但它并不限制使用 Django 特定的代码。 Django 翻译机制可用于将任意文本翻译成 Django 支持的任何语言(当然,只要存在适当的翻译目录)。您可以加载翻译目录,激活它并将文本翻译成您选择的语言,但请记住切换回原始语言,因为激活翻译目录是在每个线程的基础上完成的,这样的更改会影响在同一线程中运行的代码.

    【讨论】:

    • 是的,就用from django.utils import translation; translation.activate(language_code)
    猜你喜欢
    • 2011-06-09
    • 1970-01-01
    • 2014-11-04
    • 2011-01-04
    • 1970-01-01
    • 1970-01-01
    • 2012-02-15
    • 1970-01-01
    • 2012-06-26
    相关资源
    最近更新 更多