2010-01-12 10 views
7

Como todos sabemos (o debería), se puede usar el sistema de plantillas de Django para hacer que los cuerpos de correo electrónico:correo electrónico de plantillas de 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)), '[email protected]', [email,]) 

Esto tiene un defecto en mi mente: para editar el asunto y el contenido de una correo electrónico, debe editar tanto la vista como la plantilla. Si bien puedo justificar el acceso de los usuarios administradores a las plantillas, ¡no les estoy dando acceso a python en bruto!

Lo que sería realmente interesante es si se puede especificar bloques en el correo electrónico y tirar de ellos por separado cuando se envía el correo electrónico:

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

Pero ¿cómo hacer eso? ¿Cómo harías para renderizar solo un bloque a la vez?

Respuesta

11

Esta es mi tercera iteración de trabajo. Se suponiendo que tiene una plantilla de correo electrónico de esta manera:

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

He refactorizado para repetir el envío de correo electrónico a través de una lista por defecto y hay métodos de utilidad para enviar a un solo correo electrónico y django.contrib.authUser s (simples y múltiples) Estoy cubriendo quizás más de lo que necesitaré sensiblemente, pero ahí lo tienes.

También podría haber llegado a la cima con 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'), '[email protected]', [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) 

Como siempre, si puede mejorar eso, hágalo.

+0

Bueno & * # $ mí. Funciona. Se está considerando agregar más campos a la base para permitir establecer las configuraciones from/from-name/reply-to. – Oli

+0

Hah, he estado haciendo esto con tres plantillas diferentes, que es un PITA. ¡Definitivamente +1 de mi parte! –

+0

Me gusta. Siempre había usado plantillas separadas, lo que funciona bien, pero esto es mucho más agradable de tratar (especialmente porque generalmente quiere el mismo contexto para todas las plantillas de todos modos). –

0

Simplemente use dos plantillas: una para el cuerpo y otra para el sujeto.

+0

Dos archivos significa dos nombres de archivo para esencialmente lo mismo. Es solo un dolor por detrás tener que estar al tanto de muchas plantillas. – Oli

0

no pude conseguir la herencia de plantillas para trabajar utilizando los {% body %} etiquetas, por lo que cambió a una plantilla como esta:

{% extends "base.txt" %} 

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

Ahora tenemos que hacer que la plantilla de tres veces, pero la herencia que funciona correctamente.

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() 

también me ha sido necesario para apagar autoescape cuando se representa el texto no HTML para evitar escapado de texto en el correo electrónico

Cuestiones relacionadas