Шаблоны писем в Джанго - PullRequest
       17

Шаблоны писем в Джанго

7 голосов
/ 12 января 2010

Как мы все знаем (или должны), вы можете использовать систему шаблонов Django для рендеринга тел электронной почты:

def email(email, subject, template, context):
    from django.core.mail import send_mail
    from django.template import loader, Context

    send_mail(subject, loader.get_template(template).render(Context(context)), 'from@domain.com', [email,])

У меня есть один недостаток: редактировать тему и содержание электронной почты,Вы должны редактировать как вид, так и шаблон.Хотя я могу оправдать предоставление пользователям-администраторам доступа к шаблонам, я не дам им доступ к сырому питону!

Что было бы действительно здорово, если бы вы могли указывать блоки в электронной почте и извлекать их отдельно, когдаВы отправляете электронное письмо:

{% block subject %}This is my subject{% endblock %}
{% block plaintext %}My body{% endblock%}
{% block html %}My HTML body{% endblock%}

Но как бы вы это сделали?Как бы вы пошли рендеринг только один блок за раз?

Ответы [ 3 ]

11 голосов
/ 12 января 2010

Это моя третья рабочая итерация. Предполагается, что у вас есть шаблон электронной почты, например, так:

{% block subject %}{% endblock %}
{% block plain %}{% endblock %}
{% block html %}{% endblock %}

Я рефакторинг для повторения отправки электронной почты по списку по умолчанию, и есть служебные методы для отправки на одно письмо и django.contrib.auth User s (один и несколько) Я покрываю, пожалуй, больше, чем мне нужно, но вот, пожалуйста.

Я тоже мог бы переиграть с Python-love.

def email_list(to_list, template_path, context_dict):
    from django.core.mail import send_mail
    from django.template import loader, Context

    nodes = dict((n.name, n) for n in loader.get_template(template_path).nodelist if n.__class__.__name__ == 'BlockNode')
    con = Context(context_dict)
    r = lambda n: nodes[n].render(con)

    for address in to_list:
        send_mail(r('subject'), r('plain'), 'from@domain.com', [address,])

def email(to, template_path, context_dict):
    return email_list([to,], template_path, context_dict)

def email_user(user, template_path, context_dict):
    return email_list([user.email,], template_path, context_dict)

def email_users(user_list, template_path, context_dict):
    return email_list([user.email for user in user_list], template_path, context_dict)

Как всегда, если вы можете улучшить это, пожалуйста, сделайте.

0 голосов
/ 29 марта 2012

Мне не удалось заставить наследование шаблонов работать с использованием тегов {% body %}, поэтому я переключился на такой шаблон:

{% extends "base.txt" %}

{% if subject %}Subject{% endif %}
{% if body %}Email body{% endif %}
{% if html %}<p>HTML body</p>{% endif %}

Теперь мы должны визуализировать шаблон три раза, но наследование работает правильно.

c = Context(context, autoescape = False)
subject = render_to_string(template_name, {'subject': True}, c).strip()
body = render_to_string(template_name, {'body': True}, c).strip()
c = Context(context, autoescape = True)
html = render_to_string(template_name, {'html': True}, c).strip()

Я также счел необходимым отключить автоэкранирование при рендеринге не-HTML текста, чтобы избежать экранирования текста в электронном письме

0 голосов
/ 13 января 2010

Просто используйте два шаблона: один для тела и один для предмета.

...