Django切换,用于一段代码,切换语言以便翻译为一种语言

20 投票
5 回答
9829 浏览
提问于 2025-04-16 13:25

我有一个使用 Django 的项目,这个项目里有一个工作进程专门负责给用户发送邮件。这个工作进程会监听一个叫 RabbitMQ 的服务器,获取发送邮件所需的所有信息,比如邮件内容、模板变量、收件人的邮箱地址等等。邮件的内容是通过 Django 模板生成的,使用的是 render_to_string 方法。

不过,我想让这个邮件功能支持多语言。因为我们的一些用户会使用英语,有些用户则会使用其他语言,他们应该收到自己语言的邮件。我尝试对邮件工作进程进行国际化(使用 django.utils.translations.ugettext/ugettext_lazy),这样邮件的主题和内容就可以使用 _(...) 或者 {% blocktrans %} 来处理。

但是,由于邮件是在一个不同的后台工作进程中生成和发送的,Django 的正常 语言检测过程 似乎不适用。因为没有用户会话、没有 cookies,也没有 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 切换到特定的语言代码,这样 _() 就能使用这个语言代码了?

5 个回答

15

你可以通过上下文管理器来优雅地设置语言:

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'):
    ...
48

正如@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自带的功能,所以依赖的东西更少……

14

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

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

要小心使用这个,因为它会改变这个过程/线程在后续执行中的上下文。

撰写回答