As we all know (or should), you can use Django's template system to render email bodies:
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,])
This has one flaw in my mind: to edit the subject and content of an email, you have to edit both the view and the template. While I can justify giving admin users access to the templates, I'm not giving them access to the raw python!
What would be really cool is if you could specify blocks in the email and pull them out separately when you send the email:
{% block subject %}This is my subject{% endblock %}
{% block plaintext %}My body{% endblock%}
{% block html %}My HTML body{% endblock%}
But how would you do that? How would you go about rendering just one block at a time?
This is my third working iteration. It assuming you have an email template like so:
{% block subject %}{% endblock %}
{% block plain %}{% endblock %}
{% block html %}{% endblock %}
I've refactored to iterate the email sending over a list by default and there are utility methods for sending to a single email and django.contrib.auth
User
s (single and multiple). I'm covering perhaps more than I'll sensibly need but there you go.
I also might have gone over the top with 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)
As ever, if you can improve on that, please do.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With