【问题标题】:Pass a lazy translation string including variable to function in Django传递包含变量的惰性翻译字符串以在 Django 中运行
【发布时间】:2012-03-07 18:25:54
【问题描述】:

在 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])

模板以每个用户的正确语言呈现。但是,主题作为评估和翻译的字符串传递给 send_notifications,因此不会被翻译。

我尝试使用惰性翻译和 lambda 函数作为参数,但没有成功。任何帮助表示赞赏:)

【问题讨论】:

    标签: django internationalization translation lazy-evaluation


    【解决方案1】:

    不要传递已翻译的主题,而是传递未翻译的主题:

    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
    

    因此,更明显的是,您不会按使用情况呈现电子邮件。

    这种轻微的改写应该会让您怀疑最初选择的几个名称(locals、notification_template)。

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

    【讨论】:

    • 感谢 jpic。这是一个非常好的答案 - 刚刚投了赞成票!然而,问题是:send_notification 不知道主题中使用的用户变量——它是一个非常通用的通知函数。所以我无法访问主题模板中的“用户”对象:-P
    • 哦,对您的原始答案非常酷!谢谢!我没有收到有关更改的通知,只是偶然偶然发现了它。
    【解决方案2】:

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

    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
    

    似乎可以正常工作 :) 由于我们正在处理几种不同的通知,因此我尽量避免为每种类型使用额外的模板。但是,使用 extra_context 调用模板也是一种可能的解决方案。

    【讨论】:

      【解决方案3】:

      我最终创建了一个处理翻译的类,将字符串的上下文传递给这个类。

      from django.utils.translation import gettext_lazy as _
      
      class Translatable(object):
          def __init__(self, text, context):
              self.text = text
              self.context = context
      
          def __str__(self):
              return _(self.text).format(**self.context)
      

      在你的函数中,只需调用str(subject):

      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(str(subject), render_to_string('notification_email.txt', locals()), settings.SERVER_EMAIL, [s.user.email])
      

      并传递给您的功能如下:

      subject = Translatable(_("{user} has posted a comment"), context={'user': user})
      send_notifications(request, subject, url)
      

      【讨论】:

        猜你喜欢
        • 2011-12-25
        • 1970-01-01
        • 1970-01-01
        • 2023-03-09
        • 2021-10-04
        • 2012-05-03
        • 1970-01-01
        • 2014-05-21
        • 1970-01-01
        相关资源
        最近更新 更多