Django切换,用于一段代码,切换语言以便翻译为一种语言
我有一个使用 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 个回答
你可以通过上下文管理器来优雅地设置语言:
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'):
...
正如@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自带的功能,所以依赖的东西更少……
切换语言最简单的方法是:
from django.utils.translation import activate
activate('en')
# do smthg
activate('pl')
# do something in other language
要小心使用这个,因为它会改变这个过程/线程在后续执行中的上下文。