Передать ленивую строку перевода, включая переменную, в функцию в Django - PullRequest
2 голосов
/ 07 марта 2012

В представлении Django я создаю тему следующим образом:

subject = _(u"%(user)s has posted a comment") % { 'user': user }

Затем я передаю эту тему функции, которая обрабатывает почтовые уведомления:

send_notifications(request, subject, url)

В send_notifications,Я перебираю все подписки и отправляю электронные письма.Однако у каждого пользователя может быть свой язык, поэтому я динамически активирую язык пользователя с помощью активации Django:

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 и, таким образом, не переводится.

Я играл с ленивыми переводами и лямбда-функциями в качестве параметров, но безуспешно.Любая помощь приветствуется:)

Ответы [ 2 ]

1 голос
/ 08 марта 2012

Хорошо, нашел решение сам.На случай, если кто-нибудь столкнется с подобной проблемой:

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 также является возможным решением.

1 голос
/ 07 марта 2012

Вместо того, чтобы передавать переведенную тему, просто передайте ее без перевода:

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, messages_template).

Приведенный выше пример кода является всего лишь «образованным предположением», и вам следует дважды проверить его и убедиться, что вы все понимаете, прежде чем вставить его.

...