• Stars
    star
    680
  • Rank 66,440 (Top 2 %)
  • Language
    Python
  • License
    MIT License
  • Created over 13 years ago
  • Updated about 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Django module to easily send templated emails using django templates, or using a transactional mail provider (mailchimp, silverpop, etc.)

Django-Templated-Email

GitterBadge PypiversionBadge PythonVersionsBadge LicenseBadge

Info:A Django oriented templated email sending class
Original Author:Bradley Whittington (http://github.com/bradwhittington, http://twitter.com/darb)
Maintained by:Vinta Software: https://www.vinta.com.br/
Tests:GABadge CoverageBadge

Overview

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/master: https://github.com/vintasoftware/django-templated-email/blob/master/README.rst

Requirements

  • Python (3.6, 3.7, 3.8, 3.9, 3.10, 3.11)
  • Django (3.2, 4.0, 4.1)

We highly recommend and only officially support the latest patch release of each Python and Django series.

Getting going - installation

Installing:

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

Sending templated emails

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='[email protected]',
        recipient_list=['[email protected]'],
        context={
            'username':request.user.username,
            'full_name':request.user.get_full_name(),
            'signup_date':request.user.date_joined
        },
        # Optional:
        # cc=['[email protected]'],
        # bcc=['[email protected]'],
        # 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='[email protected]',
        to=['[email protected]'],
        context={
            'username':request.user.username,
            'full_name':request.user.get_full_name(),
            'signup_date':request.user.date_joined
        },
        # Optional:
        # cc=['[email protected]'],
        # bcc=['[email protected]'],
        # headers={'My-Custom-Header':'Custom Value'},
        # template_prefix="my_emails/",
        # template_suffix="email",
)

You can also cc and bcc recipients using cc=['[email protected]'].

Your template

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.

Using with Django Anymail

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'

Inline images

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='[email protected]',
                    recipient_list=['[email protected]'],
                    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='[email protected]',
    recipient_list=['[email protected]'],
    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 %}
Notes:
  • A copy of the rendered e-mail will be stored on the database. This can grow if you send too many e-mails. You are responsible for managing it.
  • If you use InlineImage all images will be uploaded to your media storage, keep that in mind too.

Class Based Views

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:

templated_email_template_name (mandatory if you don't implement templated_email_get_template_names()):
String naming the template you want to use for the email. ie: templated_email_template_name = 'welcome'.
templated_email_send_on_success (default: True):
This attribute tells django-templated-email to send an email if the form is valid.
templated_email_send_on_failure (default: False):
This attribute tells django-templated-email to send an email if the form is invalid.
templated_email_from_email (default: settings.TEMPLATED_EMAIL_FROM_EMAIL):
String containing the email to send the email from.

Methods:

templated_email_get_template_names(self, valid) (mandatory if you don't set templated_email_template_name):
If the method returns a string it will use it as the template to render the email. If it returns a list it will send the email only with the first existing template.
templated_email_get_recipients(self, form) (mandatory):
Return the recipient list to whom the email will be sent to. ie:
def templated_email_get_recipients(self, form):
    return [form.data['email']]
templated_email_get_context_data(**kwargs) (optional):
Use this method to add extra data to the context used for rendering the template. You should get the parent class's context from calling super. ie:
def templated_email_get_context_data(self, **kwargs):
    context = super(ThisClassView, self).templated_email_get_context_data(**kwargs)
    # add things to context
    return context
templated_email_get_send_email_kwargs(self, valid, form) (optional):
Add or change the kwargs that will be used to send the e-mail. You should call super to get the default kwargs. ie:
def templated_email_get_send_email_kwargs(valid, form):
  kwargs = super(ThisClassView, self).templated_email_get_send_email_kwargs(valid, form)
  kwargs['bcc'] = ['[email protected]']
  return kwargs
templated_email_send_templated_mail(*args, **kwargs) (optional):
This method calls django-templated-email's send_templated_mail method. You could change this method to use a celery's task for example or to handle errors.

Future Plans

See https://github.com/vintasoftware/django-templated-email/issues?state=open

Using django_templated_email in 3rd party applications

If you would like to use django_templated_email to handle mail in a reusable application, you should note that:

  • Your calls to send_templated_mail should set a value for template_dir, so you can keep copies of your app-specific templates local to your app (although the loader will find your email templates if you store them in <your app>/templates/templated_email, if TEMPLATED_EMAIL_TEMPLATE_DIR has not been overridden)
  • If you do (and you should) set a value for template_dir, remember to include a trailing slash, i.e. 'my_app_email/'
  • The deployed app may use a different backend which doesn't use the django templating backend, and as such make a note in your README warning developers that if they are using django_templated_email already, with a different backend, they will need to ensure their email provider can send all your templates (ideally enumerate those somewhere convenient)

Notes on specific backends

Using vanilla_django

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=['[email protected]']              # Set a CC on the mail
bcc=['[email protected]']             # 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**

Releasing a new version of this package:

Update CHANGELOG file.

Execute the following commands:

bumpversion [major,minor,patch]
python setup.py publish
git push origin --tags

Commercial Support

Vinta Logo

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: [email protected]

More Repositories

1

django-react-boilerplate

Django 5, React, Bootstrap 5 with Python 3 and webpack project boilerplate
Python
1,918
star
2

django-role-permissions

A django app for role based permissions.
Python
650
star
3

python-linters-and-code-analysis

Python Linters and Code Analysis tools curated list
505
star
4

tapioca-wrapper

Python API client generator
Python
344
star
5

python-api-checklist

Useful checklist for building good Python library APIs, based on "How to make a good library API" PyCon 2017 talk.
335
star
6

playbook

Vinta's Best Moves Compiled
219
star
7

awesome-django-security

A collection of Django security-related tools and libs.
198
star
8

django-ai-assistant

Integrate AI Assistants with Django to build intelligent applications
Python
196
star
9

drf-rw-serializers

Generic views, viewsets and mixins that extend the Django REST Framework ones adding separated serializers for read and write operations
Python
176
star
10

classy-django-rest-framework

Detailed descriptions, with full methods and attributes, for each of Django REST Framework's class-based views and serializers.
Python
170
star
11

django-zombodb

Easy Django integration with Elasticsearch through ZomboDB Postgres Extension
Python
149
star
12

django-virtual-models

Improve performance and maintainability with a prefetching layer in your Django project
Python
146
star
13

entity-embed

PyTorch library for transforming entities like companies, products, etc. into vectors to support scalable Record Linkage / Entity Resolution using Approximate Nearest Neighbors.
Jupyter Notebook
143
star
14

celery-tasks-checklist

Useful checklist for building great Celery tasks.
117
star
15

django-apps-checklist

Useful checklist for build great Django apps. Feel free to contribute!
104
star
16

django-celerybeat-status

A library that integrates with django admin and shows in a simple GUI when your periodic are going to run next.
Python
100
star
17

deduplication-slides

"1 + 1 = 1 or Record Deduplication with Python" Jupyter Notebook
Jupyter Notebook
83
star
18

django-knowledge-share

The engine behind Vinta's Lessons Learned page.
Python
37
star
19

django-production-launch-checklist

A checklist we use here at Vinta before launching a product we've been working on.
37
star
20

tapioca-facebook

Facebook GraphAPI wrapper using tapioca
Python
28
star
21

checklist-para-propostas-pybr

Checklist para propostas de palestras para Python Brasil
25
star
22

eslint-config-vinta

Vinta's ESLint and Prettier shareable configs.
JavaScript
23
star
23

github-metrics

Script for fetching github metrics for your project.
Python
22
star
24

devchecklists-template

The template to create your checklist on Devchecklists. https://devchecklists.com
22
star
25

hub.rocks

An online jukebox with all the songs from Deezer and YouTube. Built with Django and Angular.
Python
21
star
26

django-pg-tenants

Python
20
star
27

aurorae

🌅 🌇 A tool to generate fixed-width CNAB240 files to perform bulk payments
Python
20
star
28

cookiecutter-tapioca

A cookiecutter template for new tapioca wrappers
Python
19
star
29

GPTBundle

GPTBundle, a React application toolkit, harnesses AI to convert textual content into structured forms and delivers advanced autofill suggestions.
TypeScript
19
star
30

critical-incidents-checklist

Useful checklist for dealing with recovery crisis. Based on the talk "Saving Great Projects" 2017 Python Brasil
18
star
31

production-launch-checklist

A checklist we use here at Vinta before launching a product we've been working on.
16
star
32

tapioca-twitter

Twitter API wrapper using tapioca
Python
16
star
33

safari-samesite-cookie-issue

A Django 2.1 project to reproduce WebKit Bug 188165 and Django Ticket #30250
Python
15
star
34

pull-requests-checklist

Do's and Don'ts for Pull Requests. Improve code quality and review speed.
14
star
35

tapioca-instagram

Python
11
star
36

normalizr-redux-talk

Repository containing demo and resouces for the Normalizr Redux talk
JavaScript
8
star
37

django-psi

Easily integrate Google PageSpeed Insights to your development process - with timeline visualization
Python
8
star
38

pythonwat

Slides of Python WAT talk, see README for interactive version. Or go to http://vintasoftware.github.io/pythonwat/ for the HTML compiled one. PT-BR only for now.
Jupyter Notebook
8
star
39

vinta-design-checklists

Design checklists made by our internal team
7
star
40

high-quality-software-standards-checklists

A checklist we use here at Vinta to ensure high quality software at scale
6
star
41

devchecklists.com-content

devchecklists.com
TypeScript
6
star
42

palestra-normalizacao-django

Exemplos para a palestra "Normalize até machucar, desnormalize até funcionar em Django" da Python Nordeste 2018
Python
6
star
43

vinta-feedback-checklists

Checklists about the feedback process.
6
star
44

django-data-watcher

Python
6
star
45

django-upload-files-straight-to-s3

Example project on how to upload files from the frontend straight to S3 without sending to the server using django
Python
6
star
46

bug-card-creation-checklist

Checklist with what we believe should be written whenever a bug card is written.
5
star
47

django-bug-finder

Python
5
star
48

pr-reviewer-checklist

Set of guidelines for anyone reviewing a PR to make sure it's more civilized and avoid creating a toxic feedback culture
5
star
49

ab-testing-checklist

A checklist we use when creating A/B tests on our projects
5
star
50

tapioca-youtube

Youtube API Wrapper using Tapioca
Python
4
star
51

feature-card-creation-checklist

Checklist on how to best describe on a Trello card what needs to be done in a feature
4
star
52

weekly-meeting-checklist

Checklist to avoid wasting time in meetings, focusing them on sharing knowledge, instead of updates.
4
star
53

trigger.io-tcp

trigger.io module for TCP sockets
Java
4
star
54

dojo

Python
4
star
55

sprint-meeting-checklist

Checklist with preparations we at Vinta do for every sprint meeting we
4
star
56

landing-page-creation-checklist

Checklist of concerns one must have whenever creating a landing page completely dissociated from your original homepage
4
star
57

dedupe-clustering-experiments

Experimenting new types of clustering algorithms for Dedupe library
Jupyter Notebook
4
star
58

tapioca-mailgun

Mailgun API wrapper using tapioca
Python
4
star
59

tapioca-bitbucket

Bitbucket API wrapper using tapioca
Python
3
star
60

django-sass-bower-compressor-example

Python
3
star
61

cordova-toast-plugin

Cordova toast message plugin
Java
3
star
62

celery-persistent-revokes

Celery task revokes are stored on memory or on file. This packages makes possible to easely customize how your revokes are stored (Ex.: Database).
Python
3
star
63

django-stack

Python
2
star
64

feature-development-workflow

Developing a feature is much more than just coding it what was specified. This checklist covers other points that are important for code quality and a smoother hand-off.
2
star
65

tapioca-parse

Parse REST API wrapper using tapioca
Python
2
star
66

github-monitor

Python
2
star
67

react-jest-blog-post

JavaScript
2
star
68

django-linters-talk-demo

Demos for DjangoCon 2017 talk: Preventing headaches with linters and automated checks
Python
2
star
69

user-documentation-checklists

General guidelines on how to build awesome SaaS user documentation!
2
star
70

tapioca-mandrill

Mandrill API wrapper using tapioca
Python
2
star
71

medplum-snippet-catalog

A collection of reusable code snippets and components for Medplum projects.
TypeScript
2
star
72

identity-validation

Project to validate we're actually members of Vinta Software
1
star
73

tapioca-harvest

Harvest wrapper using tapioca
Python
1
star
74

react-flux-example

JavaScript
1
star
75

rise-jupyter-talk

Slides da talk "Fazendo apresentações real-time com Jupyter" da Python Sudeste 2016
OpenEdge ABL
1
star