Use Django to send emails with SMTP

Django is a Python-based web framework that allows more control for sending emails using functions and expressions.
Register or Login to like

Numerous professions utilize simple mail transfer protocol (SMTP) to deliver emails to their end users. SMTP also retrieves messages, though that has not been its primary use case. Open source frameworks like Django, a Python-based web framework, allows more control for sending emails using functions and expressions.

This article shows how to configure an SMTP server and send emails in Django using SMTP.

Project setup and overview

Before proceeding, this tutorial requires a code editor (such as VS Code or Codium) on your preferred device. 

Start by creating a new directory using the command in the terminal:

mkdir exampledirectory

Then change into the directory using the command:

cd exampledirectory 

Within the newly created directory, create a virtual environment using the built-in venv module in the command terminal:

python -m venv 

This command creates a virtual environment within the folder created earlier. To activate it, use the following command in the terminal:

On Linux and Mac:


source .virtenv/bin/activate

On Windows:

\Scripts\activate

Creating a Django project

After activating the virtual environment, proceed to install the Django package from pip:

pip install django

Create a new Django project:

python -m django startproject NewEmailProject 

This command creates a project with the name NewEmailProject. To run the project, head to the project directory (NewEmailProject) and run the server:

python manage.py runserver

Open the link for the developmental server in a browser. You see the Django homepage with release notes.

Configuration for sending emails

Next, open the settings.py file (in the NewEmailProject folder) to customize configurations for sending emails using Django.

Scroll to the end of the code and update the file with the following code:

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.yourserver.com'
EMAIL_USE_TLS = False
EMAIL_PORT = 465
EMAIL_USE_SSL = True
EMAIL_HOST_USER = 'your@djangoapp.com'
EMAIL_HOST_PASSWORD = 'your password'

Change the value of the EMAIL_HOST depending on your email client. Here are the acceptable values for common email clients:

  • Gmail: smtp.gmail.com

  • Outlook: smtp-mail.outlook.com

  • Yahoo: smtp.mail.yahoo.com

You can change the EMAIL_PORT or leave 465 as the default.

You can use the secure socket layer (SSL) and transport socket layer (TSL) interchangeably as they specify connection security.

To figure out other custom configurations for your email server, check out the full Django Project documentation.

SMTP email backend

The EMAIL_BACKEND expression helps determine the most suitable backend when sending emails through the Django SMTP server. This variable points to smtp.EmailBackend, which receives all the parameters needed for sending emails. It tells Django to send the email to the recipient email using SMTP and not to the console.

Sending emails with SMTP

When the environment is set up and settings.py is updated, you can send emails in Django. You can use an HTML form that sends a post request of the necessary information needed for sending an email.

Create a Django application for sending emails:

python manage.py startapp mail

Next, open the settings.py file and add the Django application (mail) to the INSTALLED_APPS list:

INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"mail"]

Send mail function

In the mail application's views.py file, start by importing the EmailMessage and get_connection from django.core.mail:

from django.core.mail import EmailMessage, get_connection

The EmailMessage class is responsible for creating the email message itself. The get_connection() function returns an instance of the email backend specified in EMAIL_BACKEND.

Now create a function that accepts a POST request, which contains form data submitted from the client side. Followed by the get_connection() functions parameters containing the email configurations created in the project settings.py file.

Next, import the settings:

from django.conf import settings

This import allows access to the email configurations created in the settings.py. Next, create the variables:

subject, recipient_list,

Then you can message, and store the corresponding attributes used in the HTML form. The email_from variable contains the sender email, which is obtained from EMAIL_HOST_USER in the settings.py file.

After the variables are processed, the EmailMessage class sends an email using the sends() method, and then closes the connection. The send_email() function renders the home.html file containing the email form.

You can create a templates folder within your mail application and store the HTML files within that folder:

from django.core.mail import EmailMessage, get_connection
from django.conf import settings

def send_email(request):  
   if request.method == "POST": 
       with get_connection(  
           host=settings.EMAIL_HOST, 
     port=settings.EMAIL_PORT,  
     username=settings.EMAIL_HOST_USER, 
     password=settings.EMAIL_HOST_PASSWORD, 
     use_tls=settings.EMAIL_USE_TLS  
       ) as connection:  
           subject = request.POST.get("subject")  
           email_from = settings.EMAIL_HOST_USER  
           recipient_list = [request.POST.get("email"), ]  
           message = request.POST.get("message")  
           EmailMessage(subject, message, email_from, recipient_list, connection=connection).send()  
 
   return render(request, 'home.html')

This is a bootstrap form for generating a message:

<form method="post" action="https://opensource.com/."> 
 {% csrf_token %} 
 <div class="mb-3">
     <label for="exampleFormControlInput1" class="form-label">Receipt email address</label>
     <input type="text" class="form-control" name="email" id="exampleFormControlInput1" placeholder="Receipt email address">
   </div>
   <div class="mb-3">
     <label for="exampleInputSubject" class="form-label">Subject</label>
     <input type="text" class="form-control" name="subject" id="exampleInputSubject">
   </div>
   <div class="mb-3">
     <label for="exampleFormControlTextarea1" class="form-label">Message</label>
     <textarea class="form-control" id="exampleFormControlTextarea1" name="message" rows="3"></textarea>
   </div>
   <button type="submit" class="btn btn-primary">Send</button>
 </form>

This form sends a post request to the send_email() function. This processes the form data and sends the email to the recipients.

Now open the urls.py file in the NewEmailProject folder to create the homepage URL. Update the urlpattern list by adding the code path("", send_email) .

Sending email to multiple recipients

To specify multiple recipients when sending the same email, create a new function called send_emails within the views.py file and modify the send function code:

                                      
def send_emails(request):  
    if request.method == "POST": 
        with get_connection(  
              host=settings.EMAIL_HOST, 
        port=settings.EMAIL_PORT,  
       username=settings.EMAIL_HOST_USER,  
       password=settings.EMAIL_HOST_PASSWORD,  
        use_tls=settings.EMAIL_USE_TLS 
        ) as connection:  
            recipient_list = request.POST.get("email").split()  
            subject = request.POST.get("subject")  
            email_from = settings.EMAIL_HOST_USER  
            message = request.POST.get("message")  
            print(type(recipient_list)) 
            EmailMessage(subject, message, email_from, recipient_list, connection=connection).send()  
  
    return render(request, 'send_emails.html')

For the recipient_list variable, I'm using the Python split() method to convert the recipients email string to list so that I can email all of them.

Next, create another HTML file called send_emails.html in the templates folder and use the same form code for the home.html file within it.

To specify multiple email recipients, use a space between each email address:

first@gmail.com second@gmail.com third@gmail.com

You should also update the urlpattern list by adding the code:

path("send-emails/", send_email)

Sending HTML emails

You can also send HTML emails with Django using a slightly modified version of the send_email function:

html_message = '''<h1>this is an automated message</h1>'''
msg = EmailMessage(subject, html_message, email_from,recipient_list, connection=connection)
msg.content_subtype = "html"
msg.send()

Sending emails with attachment

To include attachment to mails, create a variable and put it in the file path in a string like this:

attachment = "mail/templates/example.png"

Then, move the EmailMessage function to a variable and call the attach_file method followed by the send method:

msg = EmailMessage(subject, message, email_from, recipient_list, connection=connection)
msg.attach_file(attachment)
msg.send()

Django email libraries

This guide on sending emails in Django would not be complete if I didn't mention the email libraries that are available to users. Here are some noteworthy email libraries.

  • Django mailer is a Django app for queuing as it saves emails in a database and sends the mail out at a designated time.
  • Django templated email aims to send templated emails. It offers features like configurable template naming and location, template inheritance, and adding recipients to the CC and BCC lists.
  • Anymail allows the use of an email service provider (ESP). By using django.core.mail, it provides a sustained API that avoids tying your code to a single ESP.

Emailing with Django

Sending emails in Django can sound daunting, but it's as simple as creating a virtual environment. You can add Django to the environment and create an email backend. Finally, you can set up an HTML template. Give it a try.

Tags
sofiiatarhonska
Team member at Mailtrap passionate about tech and sharing experience. Mailtrap is an email delivery platform that has Email Sandbox and Email API/SMTP Relay to test, send and control your emails in one place.
Creative Commons LicenseThis work is licensed under a Creative Commons Attribution-Share Alike 4.0 International License.