Welcome to Django Mail Templated documentation!¶
Django Mail Templated is a tiny wrapper around the standard EmailMessage
class and send_mail()
function that provides an easy way to create email
messages using the Django template system
The Source code is available at GitHub under MIT license.
Features¶
- Built with OOP, KISS and flexibility in mind. Really small and simple, but yet full-featured (I hope).
- Extends and mimics the built-in Django’s
EmailMessage
andsend_mail()
. Compatible as much as possible. - Fully supports Django template system including template inheritance (thanks to BradWhittington for the note about the problem).
- Supports any possible template engines and loaders.
- Supports serialisation (thanks to arjandepooter).
- Fully covered with tests.
- Tested with Django 1.4-1.9.
- Compatible with Python 3.
Table of Contents¶
Getting started¶
Installation¶
Run:
pip install django-mail-templated
And register the app in your settings file:
INSTALLED_APPS = (
...
'mail_templated'
)
It is also a good practice to ensure that the app is installed successfully and is fully compatible with your environment:
python manage.py test mail_templated
Creating templates¶
Each email template should extend mail_templated/base.tpl or its clone either directly or via descendants.
Note: newlines at the begin and end of message part blocks will be removed.
Plain text message:
{% extends "mail_templated/base.tpl" %}
{% block subject %}
Hello {{ user.name }}
{% endblock %}
{% block body %}
This is a plain text message.
{% endblock %}
HTML message:
{% extends "mail_templated/base.tpl" %}
{% block subject %}
Hello {{ user.name }}
{% endblock %}
{% block html %}
This is an <strong>html</strong> message.
{% endblock %}
Multipart message:
{% extends "mail_templated/base.tpl" %}
{% block subject %}
Hello {{ user.name }}
{% endblock %}
{% block body %}
This is a plain text part.
{% endblock %}
{% block html %}
This is an <strong>html</strong> part.
{% endblock %}
Sending messages¶
Fast method using send_mail() function:
from mail_templated import send_mail
send_mail('email/hello.tpl', {'user': user}, from_email, [user.email])
More control with EmailMessage class:
from mail_templated import EmailMessage
message = EmailMessage('email/hello.tpl', {'user': user}, from_email,
to=[user.email])
# TODO: Add more useful commands here.
message.send()
Proceed to the Advanced usage section to find more details.
Advanced usage¶
Plain text and HTML messages¶
All messages that you create with mail_templated are instances of
the mail_templated.EmailMessage
class which extends
django.core.mail.EmailMultiAlternatives
. This does not mean all messages are
multipart messages by default, but they become so if both body
and html
template blocks are not empty in the template rendering output.
{% extends "mail_templated/base.tpl" %}
{% block subject %}
Hello {{ user.name }}
{% endblock %}
{% block body %}
This is a plain text part.
{% endblock %}
{% block html %}
This is an <strong>html</strong> part.
{% endblock %}
In this case the body
part goes to the body of the email message, and the
html
part is attached as alternative.
If you define only one of html
and body
blocks, it goes to the body of
email message with appropriate content type text/plain
or text/html
.
{% extends "mail_templated/base.tpl" %}
{% block subject %}
Hello {{ user.name }}
{% endblock %}
{% block html %}
This is an <strong>html</strong> message.
{% endblock %}
The template above produces an HTML message without a plain text alternative.
Unused block is empty by default, because it is defined empty in the base template. If you override both blocks but one of them is rendered as empty string, this produces the same result as if the block is not used at all. For example, let’s review this template:
{% extends "mail_templated/base.tpl" %}
{% block subject %}Subject{% endblock %}
{% block body %}{{ plaintext_message }}{% endblock %}
{% block html %}{{ html_message }}{% endblock %}
If the plaintext_message
variable is empty then mail_templated will
create a message without the plain text part. This way you can be sure the
users will not see empty messages. However, only newlines are truncated from
the email parts (this is done for convenient template formatting).
If the part contains just one space character then it is considered as
non-empty.
Default subject and body¶
Both the mail_templated.send_mail()
function and the
mail_templated.EmailMessage
class got new parameters template_name
and context
instead of (good) old subject
and body
. However you can
still pass both old parameters as keyword arguments. In this case they will be
treated as default values. If there is no appropriate part in the message
template (or it is empty) then the default value will
be used.
Let’s review this template without subject:
{% extends "mail_templated/base.tpl" %}
{% block body %}
This is a plain text message.
{% endblock %}
Now pass default subject and body to the
send_mail()
function:
from mail_templated import send_mail
send_mail('email/without_subject.tpl', {},
'from@inter.net', ['to@inter.net'],
subject='Default subject', body='Default subject')
The default subject
will be used since there is no subject in the template.
However the default body
will be replaced by the value from the template.
The html part also overrides default body
if the body part is empty.
Base email template and inheritance¶
The email template is rendered as a solid document, and all email message parts
(subject, body and html) appears concatenated after rendering. For this purpose
the base template mail_templated/base.tpl
contains special markers for the
email message parts, so that they can be found and extracted after rendering.
This approach eliminates the dependency on the inner implementation of the Django template engine. It would be a bad idea to extract and render the blocks objects separately, because the template engine implementation tends to change. But anyway you should not worry about that markup in normal situation. Extend the base template provided by mail_templated and use the template blocks as usually.
You can define your own base template. Just ensure your base template extends
the base of the base email templates, and any content is defined inside of
blocks subject
, body
and html
.
templates/email/base.html
{% extends "mail_templated/base.tpl" %}
{% block subject %}
{{ COMPANY_NAME }} {% block subject_content %}{% endblock %}
{% endblock %}
{% block html %}
<img src="{{ COMPANY_LOGO_URL }}" />
{% block body_content %}
{% include 'templates/email/parts/standard_greetings.html' %}
{% endblock %}
{% endblock %}
Now you can extend it as usually:
templates/email/news.html
{% extends "email/base.html" %}
{% block subject_content %}{{ article.title }}{% endblock %}
{% block body_content %}
{{ block.super }}
You probably will be interested in this news:
{{ article.preview }}
{% endblock %}
As you can see, there is nothing special about template inheritance. Actually it is even not required to extend the base of the base email templates. The most base template is just a helper that adds markers to the template. It is better to use it if you want to be sure new version of the mail_templated app will be compatible with your code. But if you want, you can use your own base template with markers for the email parts.
The most base template looks like this:
mail_templated/base.tpl
{{ TAG_START_SUBJECT }}{% block subject %}{% endblock %}{{ TAG_END_SUBJECT }}
{{ TAG_START_BODY }}{% block body %}{% endblock %}{{ TAG_END_BODY }}
{{ TAG_START_HTML }}{% block html %}{% endblock %}{{ TAG_END_HTML }}
Let’s review a simple template as an example:
{% extends "mail_templated/base.tpl" %}
{% block subject %}This is a subject{% endblock %}
{% block body %}This is a plain text body{% endblock %}
{% block html %}This is an html body{% endblock %}
This will compile to:
###start_subject###This is a subject###end_subject###
###start_body###This is a plain text body###end_body###
###start_html###This is an html body###end_html###
You can see that final document contains special tags for the message parts. These markers is the main thing that the base template adds to your message. Instead of extending it, you can use the markers just in your template:
###start_subject###New for {{ week }}###end_subject###
###start_body###
Hellow, {{ username }}! Below is a list of news for {{ week }}.
###end_body###
###start_html###
Hellow, <strong>{{ username }}</strong>!
Below is a list of news for <strong>{{ week }}</strong>.
###end_html###
This is the most efficient and the most inflexible way to define your templates. They will be compiled fast, but there is a chance you will go home much later.
The format of these tags can be changed in settings.
The str.format()
method is used to format the tags. Please see
the Format String Syntax docs if you need more info about formatting.
# Default value is '###{bound}_{block}###'
MAIL_TEMPLATED_TAG_FORMAT='<!--{block}:{bound}-->'
<!--subject:start-->This is a subject<!--subject:end-->
<!--body:start-->This is a plain text body<!--body:end-->
<!--html:start-->This is an html body<!--html:end-->
If there is any probability that the format will change in the future then you probably want to use some variables. mail_templated provides such variable to the context of your templates automatically.
{{ TAG_START_SUBJECT }}This is a subject{{ TAG_END_SUBJECT }}
{{ TAG_START_BODY }}This is a plain text body{{ TAG_END_BODY }}
{{ TAG_START_HTML }}This is an html body{{ TAG_END_HTML }}
You even can change the name format for these variables if the default format conflicts with your code or you just hate it for some personal reason (unfortunately there is no format for the names of these settings, I hope this is not so important really).
# Default value is 'TAG_{BOUND}_{BLOCK}'
MAIL_TEMPLATED_TAG_VAR_FORMAT='{BLOCK}_{BOUND}'
# TODO: Define format for the format of format.
{{ SUBJECT_START }}This is a subject{{ SUBJECT_END }}
{{ BODY_START }}This is a plain text body{{ BODY_END }}
{{ HTML_START }}This is an html body{{ HTML_END }}
Finally you may decide to define your own base template:
{{ SUBJECT_START }}{% block subject %}{% endblock %}{{ SUBJECT_END }}
{{ HTML_START }}{% block body %}{% endblock %}{{ HTML_END }}
{{ BODY_START }}
Please use a modern email client to see the html part of this message.
{{ BODY_END }}
or without these tag name variables:
<!--subject:start-->{% block subject %}{% endblock %}<!--subject:end-->
<!--body:start-->{% block body %}{% endblock %}<!--body:end-->
<!--html:start-->
Please use a modern email client to see the html part of this message.
<!--html:end-->
Don’t forget to add a test
that checks the
mail_templated app with your format of templates. Something like this
would be fine:
from django.core import mail
from django.test import TestCase
from mail_templated import send_mail
class SendMailTestCase(TestCase):
def test_plain(self):
send_mail('email/test.tpl', {'name': 'User'},
'from@inter.net', ['to@inter.net'])
self.assertEqual(len(mail.outbox), 1)
message = mail.outbox[0]
self.assertEqual(message.from_email, 'from@inter.net')
self.assertEqual(message.to, ['to@inter.net'])
self.assertEqual(message.subject, 'Message for User')
self.assertEqual(message.body, 'Hello, User!')
Working with send_mail() function¶
You probably know that the API for
Django's send_mail()
function from
django.core.mail
is frozen. Any new code wanting to extend the
functionality goes to the django.core.mail.EmailMessage
class.
The mail_templated.send_mail()
function works almost exactly the same
way as the standard one. But it is much more powerful than it seems at the
first look. The magic is done by passing all extra keyword arguments to the
mail_templated.EmailMessage
class constructor, which then passes them
to the base class django.core.mail.EmailMultiAlternatives
. Thus you can use all those features that are
accessible via parameters of the EmailMessage
class constructor.
For example, you can add attachments like in this example:
send_mail(
'email/message.tpl', context_dict, from_email, [email],
attachments=[('attachment.png', content, 'image/png')])
The limitation of this feature is that you can’t attach a file from the file system. But if the content is in the variable already then this will work well for you.
You can attach alternatives the same way:
send_mail(
'email/message.tpl', context_dict, from_email, [email],
alternatives=[('HTML alternative', 'text/html')])
You can also specify cc
, bcc
, reply_to
and extra headers
.
Please review the API documentations for detailed info about parameters:
Working with EmailMessage class¶
The mail_templated.EmailMessage
class supports all the features that
are supported by the django.core.mail.EmailMultiAlternatives
class. And of course it provides ability
to use templates. If you have a complex task that can not be done in one step
then this class is probably what you need. In other case consider the
send_mail() function.
The message instance may be initialized with many various parameters. The most common case will probably look like this:
message = EmailMessage('email/message.tpl', context, from_email, [email])
But you are free to create completely empty message and initialize it later.
message = EmailMessage()
message.template_name = 'email/message.tpl'
message.context = {'user_names': []}
message.from_email = from_email
message.to = []
for user in users:
message.context['user_names'].append(user)
message.to.append(user.email)
The EmailMessage
class has all methods that are available in the base
classes, so you can use this class in the usual way.
message.attach_alternative(html_content, 'text/html')
message.attach_file(image_file_name, 'image/png')
Finally just send the message when you are done.
message.send()
As you can see this is almost regular email message object. You just set
template_name
and context
instead of subject
and body
, and all
the work is done behind the scene. But in fact you have more control that you
can use when needed. This will be described in the next sections.
Please review the API documentations for detailed info about parameters and attributes:
Loading and rendering the email template¶
The template that you specify via
template_name
on the
EmailMessage
class initialization is loaded and
rendered automatically when you call the
send()
method. It tries to do this as late
as possible. But you can take the control and force this at any time. The
EmailMessage
class provides two methods for this needs:
load_template()
and
render()
.
The most fragmented approach looks like this:
message = EmailMessage()
message.template_name = 'email/message.tpl'
message.load_template()
message.render()
message.send()
You can pass the template name either to the constructor or to the
load_template()
method:
message = EmailMessage('email/message.tpl')
message.load_template()
message = EmailMessage()
message.load_template('email/message.tpl')
You even can load it manually and then set via the
template
property.
message = EmailMessage()
message.template = get_template('email/message.tpl')
And you even can omit the call to the load_template()
method and just use
the render()
method only. When you try to render the template in any way,
it will be loaded automatically if not loaded yet.
Before you render the template, a context dict should be provided. There are also few variants how you can do this.
message = EmailMessage('email/message.tpl', context)
message.render()
message = EmailMessage('email/message.tpl')
message.context = context
message.render()
message = EmailMessage('email/message.tpl')
message.render(context)
Finally you can pass render=True
to the constructor if you want to render
it immediately.
message = EmailMessage('email/message.tpl', context, render=True)
There is also nothing wrong (expect of efficiency) if you want to load and render one template, then load and render another one.
message = EmailMessage(customer.message_template_file, context,
from_email, [email])
message.render()
if not is_valid_html(message.body):
message.load_template('email/fallback_message.tpl')
message.context.update(fallback_extra_context)
message.render()
message.send()
As you can see in this example, you can access the resulting subject and body as soon as the message is rendered.
message = EmailMessage('email/message.tpl', context, render=True)
logger.debug('Subject: ' + message.subject)
logger.debug('Body: ' + message.body)
if message.alternatives:
logger.debug('Alternarive: ' + message.alternatives[0][0])
When rendered, the message object becomes very similar to the standard Django’s
EmailMessage
class. You can check current status via
the is_rendered
property.
Serialization¶
mail_templated supports the pickle
module. You can serialize
the message object at any stage. However what really makes sense is serializing
before invoking the load_template()
method
or after invoking the render()
method.
If you decide to serialize just between the calls to these methods then you
will lost the compiled template instance, because it can not be serialized with
pickle
.
Let’s play with the email object a little.
>>> import pickle
>>> from mail_templated import EmailMessage
>>> message = EmailMessage('email/message.tpl', {})
As soon as the message exists, you can serialize it.
>>> # Serialize the message.
>>> pickled_message = pickle.dumps(message)
>>> # Let's see how it looks now.
>>> print repr(pickled_message)
"ccopy_reg\n_reconstructor\np0\n(cmail_templated.message\nEmailMessage\np1\
nc__builtin__\nobject\np2\nNtp3\nRp4\n(dp5\nS'body'\np6\nNsS'extra_headers'
\np7\n(dp8\nsS'attachments'\np9\n(lp10\nsS'_is_rendered'\np11\nI00\nsS'cc'\
np12\n(lp13\nsS'template_name'\np14\nS'mail_templated_test/plain.tpl'\np15\
nsS'alternatives'\np16\n(lp17\nsS'bcc'\np18\n(lp19\nsS'to'\np20\n(lp21\nsS'
connection'\np22\nNsS'context'\np23\n(dp24\nsS'reply_to'\np25\n(lp26\nsS'fr
om_email'\np27\nS'webmaster@localhost'\np28\nsS'subject'\np29\nNsb."
Now you can store it somewhere for later use. Then load and de-serialize the message when needed, and it is ready for further processing.
>>> # De-serialize the message.
>>> message2 = pickle.loads(pickled_message)
>>> # Check the message state.
>>> print repr(message2)
<mail_templated.message.EmailMessage object at 0x7ffb8ad2e810>
>>> print repr(message2.template)
None
>>> # The template is not loaded yet. Load the template
>>> message2.load_template()
>>> # How is it now?
>>> print repr(message2.template)
<django.template.backends.django.Template object at 0x7ffb8a11c050>
>>> # Good! It's ready for rendering.
While the template is loaded, let’s try to serialize and de-serialize it again.
>>> # Serialize/de-serialize again.
>>> message3 = pickle.loads(pickle.dumps(message2))
>>> # Is the message still alive?
>>> print repr(message3)
<mail_templated.message.EmailMessage object at 0x7ffb8ad4f790>
>>> # Yes, it's still alive, that's good. What about the template?
>>> print repr(message3.template)
None
>>> # Ooops! We lost the template object. So now we have to load it again.
>>> message3.load_template()
>>> print repr(message3.template)
<django.template.backends.django.Template object at 0x7ffb8a0fdf10>
>>> # Phew! It's here now.
Actually if lost, the template will be loaded automatically again when you try to render it. You will not see any errors. Just your code will do some useless extra work.
>>> message4 = pickle.loads(pickle.dumps(message3))
>>> print repr(message4.template)
None
>>> # Oh no! We lost it again :(
>>> message4.render()
>>> # Hmm... There is no any error!
>>> print repr(message4.template)
<django.template.backends.django.Template object at 0x7ffb8a0b4d50>
>>> # Magic? No, this is by design!
So, remember to load the template just before the rendering, not before serialization.
Once rendered, you can serialize/de-serialize it again without problems.
>>> # Check the message state.
>>> print repr([message4.is_rendered, message4.subject, message4.body])
[True, u'Test subject', u'Test body']
>>> # Continue the tortures.
>>> message5 = pickle.loads(pickle.dumps(message4))
>>> # The author said it should work fine now.
>>> print repr(message5.template)
None
>>> # :`(
>>> # :```(
>>> # But wait!
>>> print repr([message5.is_rendered, message5.subject, message5.body])
[True, u'Test subject', u'Test body']
>>> # Heh, the template is not needed anymore! :D
There are so many combination how you can load, render and serialize the message, so that I’m afraid I can’t describe all of them here. These examples should help you to construct your own combination.
Cleanup for third-party libraries¶
There are many third-party libraries that help you to work with email messages.
If a library can work with the standard django.core.mail.EmailMessage
class then it probably can work without problems with
mail_templated.EmailMessage
. However some library may be surprised
by the additional attributes on the email message object.
For example, the Djrill app will pass your template_name
to the Mandrill
service because it provides it’s own template system, and it uses the
template_name
parameter too (what a surprise!).
If something similar happens to your messages then you should wipe out
the tracks of the mail_templated app. The most easy way to do this is to
delete the conflicting attributes. The EmailMessage
class provides a
convenient method clean()
for this
purpose. It removes the most expensive and risky properties -
context
,
template
and
template_name
.
If you use the send_mail()
function then the cleanup is
invoked for you automatically just after rendering. You can disable this
behaviour by passing the clean=False
keyword argument.
If you use the EmailMessage
class then you should care
of cleanup yourself. Fortunately there are many places where you can invoke the
clean()
method either directly or via special keyword argument clean
.
# Invoke the cleanup right on the initialisation.
message = EmailMessage('email/message.tpl', {}, render=True, clean=True)
# Call the method manually after rendering.
message.render()
message.clean()
# Pass `clean=True` to the `render()` method.
message.render(clean=True)
# The `send()` method also supports this argument.
message.send(clean=True)
There is no much difference in these variants. Just choice one that makes your code clean and clear.
API Reference¶
Like the standard django.core.mail
module, mail_templated
provides two options to send an email message:
- send_mail() function for simple usage,
- EmailMessage class for advanced usage.
send_mail()¶
-
mail_templated.
send_mail
(template_name, context, from_email, recipient_list, fail_silently=False, auth_user=None, auth_password=None, connection=None, **kwargs)[source]¶ Easy wrapper for sending a single email message to a recipient list using django template system.
It works almost the same way as the standard
send_mail()
function.The main difference is that two first arguments
subject
andbody
are replaced withtemplate_name
andcontext
. However you still can pass subject or body as keyword arguments to provide static content if needed.The
template_name
,context
,from_email
andrecipient_list
parameters are required.Note
The set of possible parameters is not limited by the list below. Any additional parameters are passed to the constructor of
EmailMultiAlternatives
class.Parameters: - template_name (str) – The template name that extends
mail_templated/base.tpl with (optional) blocks
{% subject %}
,{% body %}
and{% html %}
. - context (dict) – A dictionary to be used as a context for template rendering.
- from_email (str) – The email address for the “From:” field.
- recipient_list (list) – The recipient email addresses. Each member of this list will see the other recipients in the “To:” field of the email message.
Keyword Arguments: - fail_silently (bool) – If it’s False, send_mail will raise an
smtplib.SMTPException
. See thesmtplib
docs for a list of possible exceptions, all of which are subclasses ofsmtplib.SMTPException
. - auth_user | str – The optional username to use to authenticate to the SMTP server. If
this isn’t provided, Django will use the value of the
EMAIL_HOST_USER
setting. - auth_password | str – The optional password to use to authenticate to the SMTP server. If
this isn’t provided, Django will use the value of the
EMAIL_HOST_PASSWORD
setting. - connection (EmailBackend) – The optional email backend to use to send the mail. If unspecified, an instance of the default backend will be used. See the documentation on Email backends for more details.
- subject (str) – Default message subject. Used if
{% subject %}
block is empty or does not exist in the specified email template. - body (str) – Default message body. Used if
{% body %}
block is empty or does not exist in the specified email template. - render (bool) – If
True
, render template and setsubject
,body
andhtml
properties immediately. Default isFalse
.
Returns: The number of successfully delivered messages (which can be 0 or 1 since it can only send one message).
Return type: See also
django.core.mail.send_mail()
- Documentation for the standard
send_mail()
function.
- template_name (str) – The template name that extends
mail_templated/base.tpl with (optional) blocks
EmailMessage¶
-
class
mail_templated.
EmailMessage
(template_name=None, context={}, *args, **kwargs)[source]¶ Extends standard EmailMultiAlternatives class with ability to use templates
See also
django.core.mail.EmailMessage
- Documentation for the standard email message classes.
-
__init__
(template_name=None, context={}, *args, **kwargs)[source]¶ Initialize single templated email message (which can be sent to multiple recipients).
When using with a user-specific message template for mass mailing, create new EmailMessage object for each user. Think about this class instance like about a single paper letter (you would not reuse it, right?).
The class tries to provide interface as close to the standard Django classes as possible. The main difference is that two first arguments
subject
andbody
are replaced withtemplate_name
andcontext
. However you still can pass subject or body as keyword arguments to provide static content if needed.All parameters are optional and can be set at any time prior to calling the
render()
andsend()
methods.Note
The set of possible parameters is not limited by the list below. Any additional parameters are passed to the constructor of
EmailMultiAlternatives
class.Parameters: - template_name (str) – The template name that extends
mail_templated/base.tpl with (optional) blocks
{% subject %}
,{% body %}
and{% html %}
. - context (dict) – A dictionary to be used as a context for template rendering.
- from_email (str) – The email address for the “From:” field.
- recipient_list (list) – The recipient email addresses. Each member of this list will see the other recipients in the “To:” field of the email message.
Keyword Arguments: - subject (str) – Default message subject. Used if
{% subject %}
block is empty or does not exist in the specified email template. - body (str) – Default message body. Used if
{% body %}
block is empty or does not exist in the specified email template. - render (bool) – If
True
, render template and setsubject
,body
andhtml
properties immediately. Default isFalse
. - clean (bool) – If
True
, remove any template specific properties from the message object. This may be useful if you passrender=True
. Default isFalse
.
- template_name (str) – The template name that extends
mail_templated/base.tpl with (optional) blocks
-
attach
(filename=None, content=None, mimetype=None)[source]¶ Attaches a file with the given filename and content. The filename can be omitted and the mimetype is guessed, if not provided.
If the first parameter is a MIMEBase subclass it is inserted directly into the resulting message attachments.
-
attach_alternative
(content, mimetype)¶ Attach an alternative content representation.
-
attach_file
(path, mimetype=None)[source]¶ Attaches a file from the filesystem.
The mimetype will be set to the DEFAULT_ATTACHMENT_MIME_TYPE if it is not specified and cannot be guessed or (PY3 only) if it suggests text/* for a binary file.
-
clean
()[source]¶ Remove any template specific properties from the message object.
Useful if you want to serialize rendered message without template-specific properties. Also allows to avoid conflicts with Djrill/Mandrill and other third-party systems that may fail because of non-standard properties of the message object.
The messages should be rendered already, or you will have to setup the
context
andtemplate
/template_name
after deserialization.In most cases you can pass the
clean
parameter to the constructor or another appropriate method of this class.
-
load_template
(template_name=None)[source]¶ Load a template by it’s name using the current template loaders.
Parameters: template_name (str) – The template name that extends mail_templated/base.tpl with (optional) blocks {% subject %}
,{% body %}
and{% html %}
. If not specified then thetemplate_name
property is used.
-
recipients
()[source]¶ Returns a list of all recipients of the email (includes direct addressees as well as Cc and Bcc entries).
-
render
(context=None, clean=False)[source]¶ Render email with provided context
Parameters: context (dict) – A dictionary to be used as a context for template rendering. If not specified then the context
property is used.Keyword Arguments: clean (bool) – If True
, remove any template specific properties from the message object. Default isFalse
.
-
send
(*args, **kwargs)[source]¶ Send email message, render if it is not rendered yet.
Note
Any extra arguments are passed to
EmailMultiAlternatives.send()
.Keyword Arguments: clean (bool) – If True
, remove any template specific properties from the message object. Default isFalse
.
Troubleshooting¶
If the app does not work as expected please follow the following steps:
Update to the latest version:
pip install -U django-mail-templated
Run tests within your current Django project environment:
python manage.py test mail_templated
Run tests in a standalone mode:
python -m mail_templated.tests.run
You are also very welcome to try fixing the problem by yourself:
- Fork and clone the GitHub repository.
- Add a test case that demonstrates the problem.
- Fix it and create a pull request.
Changelog¶
2.6.x¶
- Fixed a bug with default body and html message.
- Added context parameter to the render() method.
- Made the template_name parameter not required for the load_template() method.
- Removed *args from the send_mail() function.
- Disabled HTML escape in the text parts.
2.5.x¶
- Added application settings.
- Added ability to cleanup the message object (enabled in
send_mail()
by default).
2.4.x¶
- Fixed setup.py, added missing files to the package.
- Added more tests.
2.3.x¶
- Made
template_name
argument required whenrender=True
passed to__init__()
. - Removed argument
render
of methodsend()
. - Added public property
is_rendered
. - Added more tests.
2.2.x¶
- Fixed compatibility with Python 3
2.1.x¶
- Added full support of template inheritance.
- Added obligatory base email template.
- Fixed broken pickling/unpickling feature.
render=True
is now ignored on initialisation without template. Raised error before.
2.0.x¶
This is intermediate version with broken pickling/unpickling feature. Using of next or previous version is highly recommended.
- Slightly changed the list of arguments for
EmailMessage.__init__()
. - Replaced template and template_name property setters with method
load_template()
. - Added method
render()
. - Added support for late initialisation.
- Improved tests.
1.0.x¶
- Fixed the multilingual templates support for Django >= 1.8.
Contributors¶
Author:
Other contributors:
- Thomas Parslow
- Arjan de Pooter
- and other great people who help to test and improve the app.
Special thanks to Thomas Parslow