django-templated-email is oriented towards sending templated emails. The library supports template inheritance, adding cc'd and bcc'd recipients, configurable template naming and location.
The send_templated_email method can be thought of as the render_to_response shortcut for email.
Make sure you are reading the correct documentation:
develop branch: https://github.com/vintasoftware/django-templated-email/blob/develop/README.rst
stable pypi/main: https://github.com/vintasoftware/django-templated-email/blob/main/README.rst
We highly recommend and only officially support the latest patch release of each Python and Django series.
Python 3.9 is no longer supported in Django 5.0 and newer, so is only supported with Django 4.2.
Getting going - installationInstalling:
pip install django-templated-email
You can add the following to your settings.py (but it works out the box):
TEMPLATED_EMAIL_BACKEND = 'templated_email.backends.vanilla_django.TemplateBackend' # You can use a shortcut version TEMPLATED_EMAIL_BACKEND = 'templated_email.backends.vanilla_django' # You can also use a class directly from templated_email.backends.vanilla_django import TemplateBackend TEMPLATED_EMAIL_BACKEND = TemplateBackend
Example usage using vanilla_django TemplateBackend backend
Python to send mail:
from templated_email import send_templated_mail send_templated_mail( template_name='welcome', from_email='from@example.com', recipient_list=['to@example.com'], context={ 'username':request.user.username, 'full_name':request.user.get_full_name(), 'signup_date':request.user.date_joined }, # Optional: # cc=['cc@example.com'], # bcc=['bcc@example.com'], # headers={'My-Custom-Header':'Custom Value'}, # template_prefix="my_emails/", # template_suffix="email", )
If you would like finer control on sending the email, you can use get_templated_email, which will return a django EmailMessage object, prepared using the vanilla_django backend:
from templated_email import get_templated_mail get_templated_mail( template_name='welcome', from_email='from@example.com', to=['to@example.com'], context={ 'username':request.user.username, 'full_name':request.user.get_full_name(), 'signup_date':request.user.date_joined }, # Optional: # cc=['cc@example.com'], # bcc=['bcc@example.com'], # headers={'My-Custom-Header':'Custom Value'}, # template_prefix="my_emails/", # template_suffix="email", )
You can also cc and bcc recipients using cc=['example@example.com'].
The templated_email/ directory needs to be the templates directory.
The backend will look in my_app/templates/templated_email/welcome.email :
{% block subject %}My subject for {{username}}{% endblock %} {% block plain %} Hi {{full_name}}, You just signed up for my website, using: username: {{username}} join date: {{signup_date}} Thanks, you rock! {% endblock %}
If you want to include an HTML part to your emails, simply use the 'html' block :
{% block html %} <p>Hi {{full_name}},</p> <p>You just signed up for my website, using: <dl> <dt>username</dt><dd>{{username}}</dd> <dt>join date</dt><dd>{{signup_date}}</dd> </dl> </p> <p>Thanks, you rock!</p> {% endblock %}
The plain part can also be calculated from the HTML using html2text. If you don't specify the plain block and html2text package is installed, the plain part will be calculated from the HTML part. You can disable this behaviour in settings.py :
TEMPLATED_EMAIL_AUTO_PLAIN = False
You can also specify a custom function that converts from HTML to the plain part :
def convert_html_to_text(html): ... TEMPLATED_EMAIL_PLAIN_FUNCTION = convert_html_to_text
You can globally override the template dir, and file extension using the following variables in settings.py :
TEMPLATED_EMAIL_TEMPLATE_DIR = 'templated_email/' #use '' for top level template dir, ensure there is a trailing slash TEMPLATED_EMAIL_FILE_EXTENSION = 'email'
You can also set a value for template_prefix and template_suffix for every time you call send_templated_mail, if you wish to store a set of templates in a different directory. Remember to include a trailing slash.
Anymail integrates several transactional email service providers (ESPs) into Django, with a consistent API that lets you use ESP-added features without locking your code to a particular ESP. It supports Mailgun, Postmark, SendGrid, SparkPost and more.
You can use it with django-templated-email, just follow their instructions in their quick start to configure it.
Optionally you can use their custom EmailMessage class with django-templated-email by using the following settings:
# This replaces django.core.mail.EmailMessage TEMPLATED_EMAIL_EMAIL_MESSAGE_CLASS='anymail.message.AnymailMessage' # This replaces django.core.mail.EmailMultiAlternatives TEMPLATED_EMAIL_EMAIL_MULTIALTERNATIVES_CLASS='anymail.message.AnymailMessage'
You can add inline images to your email using the InlineImage class.
First get the image content from a file or a ImageField:
# From a file with open('pikachu.png', 'rb') as pikachu: image = pikachu.read() # From an ImageField # Suppose we have this model class Company(models.Model): logo = models.ImageField() image = company.logo.read()
Then create an instance of InlineImage:
from templated_email import InlineImage inline_image = InlineImage(filename="pikachu.png", content=image)
Now pass the object on the context to the template when you send the email.
send_templated_mail(template_name='welcome', from_email='from@example.com', recipient_list=['to@example.com'], context={'pikachu_image': inline_image})
Finally in your template add the image on the html template block:
<img src="{{ pikachu_image }}">
Note: All InlineImage objects you add to the context will be attached to the e-mail, even if they are not used in the template.
Add link to view the email on the web# Add templated email to INSTALLED_APPS INSTALLED_APPS = [ ... 'templated_email' ]
# and this to your url patterns url(r'^', include('templated_email.urls', namespace='templated_email')),
# when sending the email use the *create_link* parameter. send_templated_mail( template_name='welcome', from_email='from@example.com', recipient_list=['to@example.com'], context={}, create_link=True)
And, finally add the link to your template.
<!-- With the 'if' the link will only appear on the email. --> {% if email_uuid %} <!-- Note: you will need to add your site since you will need to access it from the email --> You can view this e-mail on the web here: <a href="http://www.yoursite.com{% url 'templated_email:show_email' uuid=email_uuid %}"> here </a> {% endif %}
It's pretty common for emails to be sent after a form is submitted. We include a mixin to be used with any view that inherit from Django's FormMixin.
In your view add the mixin and the usual Django's attributes:
from templated_email.generic_views import TemplatedEmailFormViewMixin class AuthorCreateView(TemplatedEmailFormViewMixin, CreateView): model = Author fields = ['name', 'email'] success_url = '/create_author/' template_name = 'authors/create_author.html'
By default the template will have the form_data if the form is valid or from_errors if the form is not valid in it's context.
You can view an example here
Now you can use the following attributes/methods to customize it's behavior:
Attributes:
Methods:
def templated_email_get_recipients(self, form): return [form.data['email']]
def templated_email_get_context_data(self, **kwargs): context = super(ThisClassView, self).templated_email_get_context_data(**kwargs) # add things to context return context
def templated_email_get_send_email_kwargs(valid, form): kwargs = super(ThisClassView, self).templated_email_get_send_email_kwargs(valid, form) kwargs['bcc'] = ['admin@example.com'] return kwargs
You can configure Django-Templated-Email by setting the following settings
TEMPLATED_EMAIL_FROM_EMAIL = None # String containing the email to send the email from - fallback to DEFAULT_FROM_EMAIL TEMPLATED_EMAIL_BACKEND = TemplateBackend # The backend class that will send the email, as a string like 'foo.bar.TemplateBackend' or the class reference itself TEMPLATED_EMAIL_TEMPLATE_DIR = 'templated_email/' # The directory containing the templates, use '' if using the top level TEMPLATED_EMAIL_FILE_EXTENSION = 'email' # The file extension of the template files TEMPLATED_EMAIL_AUTO_PLAIN = True # Set to false to disable the behavior of calculating the plain part from the html part of the email when `html2text <https://pypi.python.org/pypi/html2text>` is installed TEMPLATED_EMAIL_PLAIN_FUNCTION = None # Specify a custom function that converts from HTML to the plain part # Specific for anymail integration: TEMPLATED_EMAIL_EMAIL_MESSAGE_CLASS = 'django.core.mail.EmailMessage' # Replaces django.core.mail.EmailMessage TEMPLATED_EMAIL_EMAIL_MULTIALTERNATIVES_CLASS = 'django.core.mail.EmailMultiAlternatives' # Replaces django.core.mail.EmailMultiAlternatives
See https://github.com/vintasoftware/django-templated-email/issues?state=open
Using django_templated_email in 3rd party applicationsIf you would like to use django_templated_email to handle mail in a reusable application, you should note that:
This is the default backend, and as such requires no special configuration, and will work out of the box. By default it assumes the following settings (should you wish to override them):
TEMPLATED_EMAIL_TEMPLATE_DIR = 'templated_email/' #Use '' for top level template dir TEMPLATED_EMAIL_FILE_EXTENSION = 'email'
For legacy purposes you can specify email subjects in your settings file (but, the preferred method is to use a {% block subject %} in your template):
TEMPLATED_EMAIL_DJANGO_SUBJECTS = { 'welcome':'Welcome to my website', }
Additionally you can call send_templated_mail and optionally override the following parameters:
template_prefix='your_template_dir/' # Override where the method looks for email templates (alternatively, use template_dir) template_suffix='email' # Override the file extension of the email templates (alternatively, use file_extension) cc=['fubar@example.com'] # Set a CC on the mail bcc=['fubar@example.com'] # Set a BCC on the mail template_dir='your_template_dir/' # Override where the method looks for email templates connection=your_connection # Takes a django mail backend connection, created using **django.core.mail.get_connection** auth_user='username' # Override the user that the django mail backend uses, per **django.core.mail.send_mail** auth_password='password' # Override the password that the django mail backend uses, per **django.core.mail.send_mail**
This is a third-party backend that uses Markdown to render the email templates.
For installation and usage, see the django-templated-email-md repository, and the associated documentation.
Releasing a new version of this package:Create a new branch off develop, named like feat/update-to-x.y.z where x.y.z is the new version number.
Update CHANGELOG file.
Update the version executing:
bumpversion [major,minor,patch]
Open a pull request to merge your branch into main, and get it reviewed.
Once the pull request is approved and merged, checkout main branch and pull the latest changes.
Push the tag generated by bumpversion to the remote repository:
git push origin --tags
Create a new release on GitHub, using the tag created by bumpversion. Make sure to use the same version number as the one you set with bumpversion.
Finally, publish the new version to PyPI executing:
python -m build python -m twine upload dist/*
Update develop branch with the changes from main, and push it to the remote repository:
git checkout develop git pull origin main git push origin develop
This project, as other Vinta Software open-source projects is used in products of Vinta's clients. We are always looking for exciting work, so if you need any commercial support, feel free to get in touch: contact@vinta.com.br
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4