E-Mail-Templat in django
-
20-09-2019 - |
Frage
Wie wir alle wissen (oder sollte), können Sie Djangos Template-System verwenden E-Mail-Körper zu machen:
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,])
Dieser Fehler in meinem Kopf hat: das Thema und den Inhalt einer E-Mail zu bearbeiten, müssen Sie bearbeiten sowohl die Ansicht und die Vorlage. Während ich rechtfertigen kann Admin-Benutzer Zugriff auf die Vorlagen zu geben, bin ich ihnen nicht den Zugang zu den rohen Python geben!
Was wirklich cool wäre, wenn Sie Blöcke in der E-Mail angeben können und sie separat herausziehen, wenn Sie die E-Mail:
{% block subject %}This is my subject{% endblock %}
{% block plaintext %}My body{% endblock%}
{% block html %}My HTML body{% endblock%}
Aber wie würden Sie das tun? Wie würden Sie gehen über nur einen Block zu einem Zeitpunkt zu machen?
Lösung
Dies ist meine dritte Arbeits Iteration. Es vorausgesetzt, Sie eine E-Mail-Vorlage haben etwa so:
{% block subject %}{% endblock %}
{% block plain %}{% endblock %}
{% block html %}{% endblock %}
Ich habe zu Iterierte Refactoring die E-Mail über eine Liste von Standard-Senden und es gibt Hilfsmethoden für das Senden an einem einzigen E-Mail und django.contrib.auth
User
s (Einfach- und Mehrfach). Ich Abdeckung vielleicht mehr als ich vernünftig brauchen, aber es Sie gehen.
Ich könnte auch mit Python-Liebe über die Spitze gegangen.
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)
Wie immer, wenn Sie auf das verbessern können, bitte tun.
Andere Tipps
Just Verwendung zwei Vorlagen:. Ein für den Körper und ein für das Thema
Ich konnte nicht Vorlage Vererbung an der Arbeit mit den {% body %}
-Tags, so dass ich zu einer Vorlage wie folgt umgeschaltet:
{% extends "base.txt" %}
{% if subject %}Subject{% endif %}
{% if body %}Email body{% endif %}
{% if html %}<p>HTML body</p>{% endif %}
Jetzt müssen wir die Vorlage dreimal machen, aber die Vererbung funktioniert.
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()
Ich fand es auch notwendig autoescape auszuschalten, wenn der Nicht-HTML-Text zu vermeiden Rendering Text in der E-Mail entkam