How To Send Emails in Django

How To Send Emails in Django

Django is one of the most popular Python web framework. It is an open-source batteries included solution, which comes with a toolkit of components required for web app development. Once you’re here, you’ve already picked Django to build your app and need to set up email delivery. We’re amused to help you with that and explain details.

How to begin

To send emails in Django, you need to configure your settings.py file first. 

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.yourserver.com'
EMAIL_PORT = '<your-server-port>'
EMAIL_HOST_USER = '[email protected]'
EMAIL_HOST_PASSWORD = 'your-email account-password'
EMAIL_USE_TLS = True
EMAIL_USE_SSL = False

EMAIL_BACKEND defines email backend (custom or predefined). django.core.mail.backends.smtp.EmailBackend is the default backend, which uses SMTP server for email sending. Other variables, such as EMAIL_HOST, EMAIL_PORT and others should be set up according to the parameters of the SMTP service you use. Besides .smtp.EmailBackend, you can use backend for Amazon SES, Mailgun, SendGrid, and other services, or install Django on your self-hosted VPS.

Also, there are a few backends for testing purposes:

  •  .console.EmailBackend – a console backend. It composes emails that will be sent to the standard output. 
  •  .filebased.EmailBackend – a file backend. It creates emails in the form of a new file per each new session opened on the backend. 
  •  .locmem.EmailBackend – an in-memory backend. It stores emails in the local memory cache of django.core.mail.outbox.  
  • .dummy.EmailBackend – a dummy cache backend. It implements the cache interface and does nothing with your emails.

Time to send an email

Once you’ve set up your backend, you can send emails. For this, import the send_mail function that will use a separate connection for each message. Alternatively, you may opt for send_mass_mail. It opens a single connection to the mail server and is mostly intended to handle mass emailing. Both functions can be imported from django.core.mail.

send_mail

  • send_mail is the most basic function for email delivery in Django. It comprises four obligatory parameters to be specified: subject, message, from_email, and recipient_list. Optionally, you can specify:
  • auth_user: the username to be used for authentication at the SMTP server. 
  •  auth_password: the password to be used for authentication at the SMTP server.
  •  connection: optional email backend.
  •  html_message: for sending multipart emails.

 fail_silently: a boolean that controls error handling by the backend. True – exceptions will be silently ignored; Falsesmtplib.SMTPException will be raised. (For more about smtplib, a Python standard library, read in Send emails in Python). 

How send_mail may look:

from django.core.mail import send_mail

send_mail(
    subject = 'Email subject'
    message = 'Email body'
    from_email = ‘[email protected]’
    recipient_list = ['[email protected]',]
    auth_user = 'username'
    auth_password = 'password'
    fail_silently = True,
)

Is any customization available?

Of course! Django developers can use the EmailMessage class, which answers for the creation of a message. The basic parameters include subject, body, from_email, to, and reply_to.

Besides them, the following options are available:

  •  connection: defines an email backend instance for multiple messages. 
  •  attachments: specifies the attachment for the message.
  •  headers: specifies extra headers like Message-ID or CC for the message. 
  •  cc: specifies email addresses used in the “CC” header.

With the EmailMessage class, you can use the methods, such as:

  • send: get the message sent.
  • message: composes a MIME object (django.core.mail.SafeMIMEText or django.core.mail.SafeMIMEMultipart).
  • recipients: returns a list of the recipients specified in all the attributes including to, cc, and bcc. 
  • attach: creates and adds a file attachment. It can be called with a MIMEBase instance or a triple of arguments consisting of filename, content, and mime type.
  • attach_file: creates an attachment using a file from a filesystem. We’ll talk about adding attachments a bit later.

Check out this example:

from django.core.mail import EmailMessage

email = EmailMessage(
    subject = 'Email subject',
    body = 'Email body',
    from_email = '[email protected]',
    to = ['[email protected]'],
    bcc = ['[email protected]'],
    reply_to = ['[email protected]'],
)

Let’s send an HTML email with an attachment

Django 1.7+ lets you send emails with HTML content. This looks as follows:

from django.core.mail import send_mail
subject = 'Email subject' 
html_message = render_to_string('mail_template.html', {'context': 'values'})
plain_message = strip_tags(html_message)
from_email = '[email protected]>' 
to = '[email protected]' 

mail.send_mail(subject, plain_message, from_email, [to], html_message=html_message)

To add an attachment, you can use one of the two methods: attach or attach_file.

  • attach creates and adds a file attachment through a triple of arguments – filename, content, and mime type. 

Example:

message.attach('Attachment.pdf', file_to_be_sent, 'file/pdf')
  • attach_file uses a file from a filesystem as an attachment. 

Example:

message.attach_file('/documents/Attachment.pdf')
How to send emails with an attachment in Django, open-source python web framework

Let’s send a few emails

send_mass_mail

send_mass_mail is the way to multiple emails. Each email contains a datatuple made of subject, message, from_email, and recipient_list. Optionally, you can add other arguments that are the same as for send_mail.

Check out the following code sample:

message1 = ('Email subject #1', 
 'Email body #1',
 '[email protected]',
 ['[email protected]', '[email protected]'])
message2 = ('Email subject #2',
 'Email body #2',
 '[email protected]',
 ['[email protected]'])
message3 = ('Email subject #3',
 'Email body #3',
 '[email protected]',
 ['[email protected]'])
send_mass_mail((message1, message2, message3), fail_silently=False)

send_messages

The send_messages method is an alternative to send_mass_mail. It opens a connection for the first email and uses it to send the following ones. After that, you close the connection manually.

Check out the example below. 

from django.core import mail
connection = mail.get_connection()

connection.open()

email1 = mail.EmailMessage(
    'That’s your subject',
    'That’s your message body',
    '[email protected]',
    ['[email protected]'],
    connection=connection,
)
email1.send()

email2 = mail.EmailMessage(
    'That’s your subject #2',
    'That’s your message body #2',
    '[email protected]',
    ['[email protected]'],
)
email3 = mail.EmailMessage(
  'That’s your subject #3',
    'That’s your message body #3',
    '[email protected]',
    ['[email protected]'],
)

connection.send_messages([email2, email3])
connection.close()

Email-centered Django libraries

Now, we want to draw your attention to the libraries and apps that have many useful features for email sending.

Our selection includes five libraries:

email centered django libraries, open-source python web framework
  • django-post_office: many cool features such as asynchronous email sending, built-in scheduling, multiprocessing, etc.
  • django-mailbox: lets you import email from local mailboxes, POP3, and IMAP. You can also directly receive messages from Postfix or Exim4. 
  • django-mailer: for queuing and scheduling email sending.
  • django-templated-email: for sending templated emails.
  • django-anymail: a collection of email backends and webhooks. Here you’ll find backends for famous email services including SendGrid, Mailgun, and others.

Read more: How to Make A Blog with Django

How to test email delivery in Django?

We recommend you two solutions to do some initial testing of your email delivery: TestCase and Mailtrap.

TestCase

TestCase uses django.core.mail.backends.locmen.EmailBackend as EMAIL_BACKEND. This backend stores emails in the local memory cache – django.core.mail.outbox. So, this test runner does not actually send emails. You can use the following unit test sample to test your email sending capability.

from django.core import mail
from django.test import TestCase

class EmailTest(TestCase):
    def test_send_email(self):
        mail.send_mail(
            'Email subject', 'Email body',
            '[email protected]', ['[email protected]'],
            fail_silently=False,
        )

        self.assertEqual(len(mail.outbox), 1)        
        self.assertEqual(mail.outbox[0].subject, 'Email subject')
        self.assertEqual(mail.outbox[0].body, 'Email body')

This code will test not only your email sending but also the correctness of the subject and message body.

Mailtrap

Mailtrap can be a rich solution for testing. First, it lets you test not only the SMTP server but also the email content and do other essential checks from the email testing checklist. Second, it is a rather easy-to-use tool. All you need to do is to copy the SMTP credentials from your demo inbox and tweak your settings.py. Or you can just copy/paste these four lines from the Integrations section by choosing Django in the pop-up menu. 

EMAIL_HOST = 'smtp.mailtrap.io'
EMAIL_HOST_USER = '********'
EMAIL_HOST_PASSWORD = '*******'
EMAIL_PORT = '2525'

After that, feel free to send your HTML email with an attachment to check how it goes.

from django.core.mail import send_mail
subject = 'Email subject' 
html_message = render_to_string('mail_template.html', {'context': 'values'}) plain_message = strip_tags(html_message)
from_email = '[email protected]>' 
to = '[email protected]'

mail.send_mail(subject, plain_message, from_email, [to], html_message=html_message)
message.attach('Attachment.pdf', file_to_be_sent, 'file/pdf') 

Check out your Mailtrap Demo inbox – the email will be right there.

To wrap up

As you see, setting up email sending in Django is not rocket science. Our guide is aimed to help you cope with that task fast and seamlessly. Good luck with your Django project and may your experience be smooth and productive!

Use promo code “SKY95DJANGO” to save 95% off your first month. Offer is valid for new users only.

About the Author: Andriy is a Growth Manager at Mailtrap, a product that helps people inspect and debug emails before sending them to real users. He has over 5 years of experience in the field of marketing & product. Andriy loves to network with people. Running is his hobby and he enjoys discovering new places. You can connect with Andriy via Linkedin or Facebook

Share this post with your friends