将包含变量的惰性转换字符串传递给Django中的函数

将包含变量的惰性转换字符串传递给Django中的函数,django,internationalization,translation,lazy-evaluation,Django,Internationalization,Translation,Lazy Evaluation,在Django视图中,我创建了这样一个主题: subject = _(u"%(user)s has posted a comment") % { 'user': user } 然后我将此主题传递给一个函数,该函数处理电子邮件通知: send_notifications(request, subject, url) 在send_notifications中,我迭代所有订阅并发送电子邮件。但是,每个用户可以使用不同的语言,因此我通过Django的activate动态激活用户的语言: def se

在Django视图中,我创建了这样一个主题:

subject = _(u"%(user)s has posted a comment") % { 'user': user }
然后我将此主题传递给一个函数,该函数处理电子邮件通知:

send_notifications(request, subject, url)
在send_notifications中,我迭代所有订阅并发送电子邮件。但是,每个用户可以使用不同的语言,因此我通过Django的activate动态激活用户的语言:

def send_notifications(request, subject, url):
    from django.utils.translation import activate
    for s in Subscription.objects.filter(url=url):
        activate(s.user.userprofile.lang)
        send_mail(subject, render_to_string('notification_email.txt', locals()), settings.SERVER_EMAIL, [s.user.email])
模板以每个用户的正确语言呈现。但是,主题作为经过计算和翻译的字符串传递给发送通知,因此不会被翻译


我使用惰性翻译和lambda函数作为参数,但没有成功。感谢您的帮助:)

不要传递已翻译的主题,只需传递未翻译的主题即可:

subject = '%(user)s has posted a comment'
context = {'user': user}

def send_notifications(request, subject, url, context):
    from django.utils.translation import activate
    for s in Subscription.objects.filter(url=url):
        activate(s.user.userprofile.lang)
        send_mail(_(subject) % context, render_to_string('notification_email.txt', locals()), settings.SERVER_EMAIL, [s.user.email])
如果您不打算对每个用户的内容进行个性化设置,那么您最好限制渲染的数量,因为这有点令人困惑:

# also do your imports at the top to catch import issues early
from django.utils.translation import activate
from django.utils.translation import ugettext as _

def send_notifications(request, url, 
    translatable_subject, context,
    body_template='notification_template.txt'):
    previous_lang = None
    for s in Subscription.objects.filter(url=url).order_by('user__userprofile__lang'):
        if s.user.userprofile.lang != previous_lang:
            activate(s.user.userprofile.lang)
            subject = _(translatable_subject) % context
            body = render_to_string(body_template, locals())
        send_mail(subject, body, settings.SERVER_EMAIL, [s.user.email])
        previous_lang = s.user.userprofile.lang
因此,更明显的是,您不会按照每次使用情况呈现电子邮件

这种轻微的重写会让您怀疑最初选择的几个名称(本地名称、通知模板)


上面的示例代码仅仅是一个“有根据的猜测”,在粘贴之前,您应该仔细检查并确保理解所有内容。

好的,我自己找到了解决方案。如果任何人遇到类似问题:

from django.utils.translation import ugettext as _

# create subject as raw string in Django view
raw_subject = r"%(username)s has posted a comment"

# for the sake of generic variables, create a dictionary to pass to function
extra_context = { 'user': user }

# call function with raw string and dictionary as params
send_notifications(request, raw_subject, url, extra_context)

# translate the raw string inside send_notifications into the temporarily activated language
translated_subject = _(raw_subject) % extra_context

似乎正在按预期工作:)由于我们正在处理几种不同的通知,我试图避免为每种通知使用额外的模板。不过,调用具有额外上下文的模板也是一种可能的解决方案。

谢谢jpic。这是一个非常好的答案——刚刚投票通过!但是,问题是:send_notification不知道主题中使用的用户变量-这是一个非常通用的通知函数。因此,我无法访问主题模板中的“用户”对象:-POh,对原始答案的添加非常酷!谢谢我没有收到关于变更的通知,只是偶然发现了它。