Last active
March 5, 2016 08:49
-
-
Save SmileyChris/5881290 to your computer and use it in GitHub Desktop.
Handle template-base email messages in Django
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from email.Utils import formataddr | |
import os | |
from django.conf import settings | |
from django.core import mail | |
from django import template | |
from django.template.loader import select_template, get_template | |
def template_email(template_name, extra_context=None, *args, **kwargs): | |
""" | |
Return an :cls:`~django.core.mail.EmailMessage` with the body (and | |
optionally, the subject) set from django templates. | |
:param template_name: The template name, or partial template name. | |
:param extra_context: A dictionary of context data to pass to the email | |
templates. | |
Passing the full template name will render the email body using this | |
template. If the template extension is ``htm`` or ``html``, the message | |
mime subtype will be changed to ``html``. For example:: | |
message = template_email( | |
template_name='emails/alert.txt', subject="Alert!", | |
to=['[email protected]']) | |
message.send() | |
Passing a partial template allows a plain text body, an HTML alternative, | |
and the subject to all be templates. For example, calling | |
``template_email(template_name='emails/welcome')`` will look for the | |
following templates: | |
* ``emails/welcome_subject.txt`` will set the message's subject line. Only | |
the first non-blank line of this file will be used. | |
* ``emails/welcome.txt`` will be the plain text body. | |
* ``emails/welcome.html`` will be the HTML alternative if a plain text body | |
is also found, otherwise it'll be the body and the message mime subtype | |
will be changed to ``html``. | |
If neither the plain text or HTML template exist, a | |
:cls:`~django.template.TemplateDoesNotExist` exception will be raised. The | |
subject template is optional. | |
The subject and plain text body templates are rendered with auto-escape | |
turned off. | |
""" | |
message = mail.EmailMultiAlternatives(*args, **kwargs) | |
context = template.Context(extra_context) | |
html_template_names = ['{}.html'.format(template_name)] | |
txt_template_names = ['{}.txt'.format(template_name)] | |
if os.path.splitext(template_name)[1].lower() in ('.htm', '.html'): | |
html_template_names.append(template_name) | |
else: | |
txt_template_names.append(template_name) | |
# Get the HTML body. | |
try: | |
html = select_template(html_template_names).render(context) | |
except template.TemplateDoesNotExist: | |
html = None | |
# The remainder of the templates are text only, so turn off autoescaping. | |
context.autoescape = False | |
# Get the plain-text body. | |
try: | |
txt = select_template(txt_template_names).render(context) | |
except template.TemplateDoesNotExist: | |
if not html: | |
# Neither body template exists. | |
raise | |
txt = None | |
# Get the subject. | |
try: | |
subject = ( | |
get_template('{}_subject.txt'.format(template_name)) | |
.render(context) | |
) | |
message.subject = subject.strip().splitlines()[0] | |
except template.TemplateDoesNotExist: | |
pass | |
if txt: | |
message.body = txt | |
if html: | |
message.attach_alternative(html, 'text/html') | |
else: | |
message.content_subtype = 'html' | |
message.body = html | |
return message | |
def template_mail_managers(**kwargs): | |
return _template_email_convenience(to=settings.MANAGERS, **kwargs) | |
def template_mail_admins(**kwargs): | |
return _template_email_convenience(to=settings.ADMINS, **kwargs) | |
def _template_email_convenience(to, fail_silently=False, **kwargs): | |
to = [formataddr(recipient) for recipient in to] | |
final_kwargs = {'from_email': settings.SERVER_EMAIL} | |
final_kwargs.update(kwargs) | |
message = template_email(to=to, **final_kwargs) | |
if settings.EMAIL_SUBJECT_PREFIX: | |
message.subject = ( | |
settings.EMAIL_SUBJECT_PREFIX + message.subject) | |
message.send(fail_silently=fail_silently) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment