Sending emails from a form in Django 3.0

by Alex

In this content, let’s create a simple contact form to send emails from the Django 3.0 website. We will take advantage of the built-in email support which will allow us to send emails effortlessly using the SendGrid service. Archive with the project contact.rar

Initial setup

If you already know how to create a jango application, you can skip this step. Create the project – config, the application – sendemail and the virtual environment contact

. The first step is to create a separate folder for the project. Create it manually or from the terminal. At the command line (Mac or Linux, for Windows some commands are different) run the following commands to go to the desired directory and create a new folder “contact”.

$ mkdir contact && cd contact

Now you can install Django and activate the virtual environment.

Note: If you don’t have pipenv installed, start with pip install pipenv

$ pipenv install django==3.0.5
$ pipenv shell

Next, create a new Django project called config in the sendemail application:

(contact) $ django-admin startproject config .
(contact) $ python startapp sendemail

To make sure everything works, let’s run migrate and runserver.

(contact) $ python migrate
(contact) $ python runserver

If you now open the link, you should see something like this:

Sending emails from a form in Django 3.0Update

The created application should now be explicitly added to the Django project. In the file you should write sendemail in the INSTALLED_APPS section.

# config/
   'sendemail.apps.SendemailConfig', # new line

Then in the same file you should create DEFAULT_FROM_EMAIL – ваша@почта.com and RECIPIENTS_EMAIL – the list of default recipient mails. It’s also worth updating EMAIL_BACKEND, specifying which email backend is being used – in this case it’s console. This is needed so that mail is output on the command line.

# config/
RECIPIENTS_EMAIL = ['[email protected] ' ] # replace with your mail
DEFAULT_FROM_EMAIL = ' [email protected]' # change to your mail
EMAIL_BACKEND = ' django.core.mail.backends.console.EmailBackend'


After adding the application to your Django project, you need to update the root config/ file by adding include on the top line, as well as a new urlpattern in the application:

# config/
from django. contrib admin
from django.urls import path, include

urlpatterns = [
    path('', include('sendemail.urls')),

Next, create the sendemail/ file in the application manually or:

touch sendemail/

Now this code. It will make the main contact form available via the email/ link, and a successful send will redirect to success/.

# sendemail/
from django. contrib admin
from django.urls. import path

from .views import contact_view, success_view

urlpatterns = [
    path('contact/', contact_view, name='contact'),
    path('success/', success_view, name='success'),


Inside the sendemail application you now need to create a new file.

touch sendemail/

It will contain all the fields for the form itself. We need three: from_email, subject and message.

# sendemail/
from django import forms

class ContactForm(forms.Form):
    from_email = forms.EmailField(label='Email', required=True)
    subject = forms.CharField(label='Subject', required=True)
    message = forms.CharField(label='Message', widget=forms.Textarea, required=True)

We’ll use the Django Forms API to quickly create the three fields.


Create a view that will do the basic work for the contact form. Update the existing sendemail/ file:

from django.shortcuts import render

from django.core.mail import send_mail, BadHeaderError
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render, redirect
from .forms import ContactForm
from config.settings import RECIPIENTS_EMAIL, DEFAULT_FROM_EMAIL

def contact_view(request):
   # if GET method, return form
  if request.method == 'GET':
        form = ContactForm()
   elif request.method == ' POST':
       # if POST method, check the form and send the email
       form = ContactForm(request.POST)
       if form.is_valid():
            subject = form.cleaned_data['subject']
            from_email = form.cleaned_data['from_email']
            message = form.cleaned_data['message']
                send_mail(f'{subject} from {from_email}', message,
                          DEFAULT_FROM_EMAIL, RECIPIENTS_EMAIL)
           except BadHeaderError:
               return HttpResponse('Error in email subject line.')
           return redirect('success')
       return HttpResponse('Invalid request.')
   return render(request, "email.html", {'form': form})

def success_view(request):
   return HttpResponse('Received! Thank you for your request.')

First, let’s import send_email and BadHeaderError for security. After that, let’s add a reference to the ContactForm class that was created in the file.

Creating templates

As a final step, we need to create templates for the message and the successful send page. To do that, use the new templates folder in the project directory.

(contact) $ mkdir templates
(contact) $ touch templates/email.html

Now update the file so that Django knows where to find the templates folder. Let’s update the DIRS setting in TEMPLATES.

# config/
       'DIRS': [os.path.join(BASE_DIR, 'templates')],

Next, update the template files themselves using the following code:

<!DOCTYPE html>
<html lang="en">
  <meta charset="UTF-8">
  <title>Message example</title>
<link rel="stylesheet" href="">
  <h1 class="text-center">Feed</h1>
  <div class="container text-center">
    <div id="form_container">
      <form method="post">
        {% csrf_token %}
        {{ form.as_p }}
        <div class="form-actions form-group">
          <button type="submit" class="form-control btn btn-success">Send</button>

Sending the first message

Make sure the server is running with the python runserver command and open in your browser. Fill out the form and click Submit. Sending emails from a form in Django 3.0The program will redirect to if the message has been sent. Sending emails from a form in Django 3.0And the console should show that the message has been sent:

Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 8bit
Subject: =?utf-8?b?0J/RgNC40LLQtdGC?
From: [email protected]
To: [email protected]
Date: Sat, 03 Oct 2020 11:10:29 -0000
Message-ID: <[email protected]>

Email service

To actually send messages, you need to set up a service: SendGrid, mailgun, or SES. Fortunately, they are very easy to use in Django. To use SendGrid, you need to create a free account and select the SMTP option. It’s easier to configure when working with the Web API. You need to verify the sender. Instructions are available at this link. Previously it was possible to send messages from free addresses ( or, but now this will not work because of the DMARC email authentication protocol. So to really send messages you need a mail on your domain, the ownership of which will have to be confirmed. Sending emails from a form in Django 3.0After adding the sender on the page , confirm the mail and move on to setting up the Web API The next window requires a name for the API key. After that you need to click on Create Key. Sending emails from a form in Django 3.0Follow the instructions. At the time of writing you need to install sendgrid library and send a test letter. You can use this file When you have gone through all the steps, you will see a successful connection message: Sending emails from a form in Django 3.0Next, update the file to change the console to smtp in EMAIL_BACKEND and add a few more fields. As well as EMAIL_HOST_PASSWORD with the SendGrid account key.

# config/
# mails to receive mails
RECIPIENTS_EMAIL = ['[email protected]']
# default sender mail, the one that is verified
DEFAULT_FROM_EMAIL = '[email protected]'
EMAIL_BACKEND = ' django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST_USER = 'apikey'
# your unique apikey from the sendgrid website

Let’s go back to, fill out and submit the form again. It works!

Sending emails from a form in Django 3.0Retrieved from

After all these steps, you’ll have a working application with the ability to send real messages from Django. This is often needed for user registration, password resets, quick replies, and so on.

Related Posts