2010-01-12 16 views
7

jak wszyscy wiemy (lub powinien), można użyć systemu szablonów Django do renderowania ciał email:email szablonów w 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,]) 

ta ma jedną wadę w mojej głowie: aby edytować temat i treść e-mail, musisz edytować zarówno widok, jak i szablon. Chociaż mogę uzasadnić przyznanie użytkownikom administracyjnym dostępu do szablonów, nie zapewniam im dostępu do surowego pythona!

Co byłoby naprawdę fajnie jest, jeśli można określić bloki w wiadomości e-mail i wyciągnąć je oddzielnie po wysłaniu e-mail:

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

Ale jak to zrobić? Jak wyglądałbyś renderując tylko jeden blok na raz?

Odpowiedz

11

To jest moja trzecia robocza iteracja. To zakładając, że masz szablon e-mail tak:

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

Mam refactored iteracyjne wysyłanie e-maila na listę domyślnie i istnieją metody użytkowe do wysyłania wiadomości e-mail do jednego i django.contrib.authUser s (pojedyncze i wielokrotne). Obejmuję być może więcej niż rozsądnie potrzebuję, ale proszę.

Mogłem też przejść na szczyt z miłością Pythona.

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) 

Jak zawsze, jeśli możesz poprawić to, proszę.

+0

Well & * $ # me. To działa. Rozważ dodanie dodatkowych pól do podstawy, aby umożliwić ustawienie ustawień from/from-name/reply-to. – Oli

+0

Hah, robiłem to z trzema różnymi szablonami, którymi jest PITA. Zdecydowanie +1 ode mnie! –

+0

Podoba mi się. Zawsze używałam tylko osobnych szablonów, które działają dobrze, ale jest o wiele przyjemniej, z którymi należy sobie poradzić (zwłaszcza, że ​​ogólnie chcesz mieć ten sam kontekst dla wszystkich szablonów). –

0

Wystarczy użyć dwóch szablonów: jednego dla ciała i drugiego dla tematu.

+0

Dwa pliki oznaczają dwie nazwy plików dla zasadniczo tej samej rzeczy. To tylko ból w tyle, który musi być na szczycie wielu szablonów. – Oli

0

nie mogłem dostać szablon dziedziczenie pracować używając {% body %} znaczniki, więc przeszedłem do szablonu tak:

{% extends "base.txt" %} 

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

Teraz mamy do renderowania szablon trzy razy, ale dziedziczenie działa prawidłowo.

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

Znalazłem również konieczne, aby wyłączyć autoescape podczas renderowania HTML non-tekst, aby uniknąć uciekł tekstu w wiadomości

Powiązane problemy