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
Table of Contents
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 environmentcontact
. 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”.
$ cd ~/PATH_WAY_TO_PAKE
$ mkdir contact && cd contact
Now you can install Django and activate the virtual environment.
Note: If you don’t have
pipenv
installed, start withpip 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 manage.py startapp sendemail
To make sure everything works, let’s run migrate
and runserver
.
(contact) $ python manage.py migrate
(contact) $ python manage.py runserver
If you now open the link 127.0.0.1:8000, you should see something like this:
Update settings.py
The created application should now be explicitly added to the Django project. In the settings.py
file you should write sendemail
in the INSTALLED_APPS
section.
# config/settings.py
INSTALLED_APPS [
'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/settings.py
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'
Updating urls.py
After adding the application to your Django project, you need to update the root config/urls.py
file by adding include
on the top line, as well as a
new urlpattern
in the application:
# config/urls.py
from django. contrib admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('sendemail.urls')),
]
Next, create the sendemail/urls.py
file in the application manually or:
touch sendemail/urls.py
Now this code. It will make the main contact form available via the email/
link, and a successful send will redirect to success/
.
# sendemail/urls.py
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'),
]
Creating forms.py
Inside the sendemail
application you now need to create a new forms.py
file.
touch sendemail/forms.py
It will contain all the fields for the form itself. We need three: from_email
, subject
and message
.
# sendemail/forms.py
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.
Creating views.py
Create a view that will do the basic work for the contact form. Update the existing sendemail/views.py
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']
try:
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')
else:
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 forms.py
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 settings.py
file so that Django knows where to find the templates folder. Let’s update the DIRS
setting in TEMPLATES
.
# config/settings.py
TEMPLATES = [
{
...
'DIRS': [os.path.join(BASE_DIR, 'templates')],
...
},
]
Next, update the template files themselves using the following code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Message example</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
</head>
<body>
<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>
</div>
</form>
</div>
</div>
</body>
</html>
Sending the first message
Make sure the server is running with the python manage.py runserver
command and open http://127.0.0.1:8000/contact
in your browser. Fill out the form and click Submit
. The program will redirect to
http://127.0.0.1:8000/success
if the message has been sent. And 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 (gmail.com or yahoo.com), 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. After adding the sender on the https://app.sendgrid.com/settings/sender_auth/senders/new page , confirm the mail and move on to setting up the Web API https://app.sendgrid.com/guide/integrate/langs/python. The next window requires a name for the API key. After that you need to click on
Create Key
. Follow the instructions. At the time of writing you need to install
sendgrid
library and send a test letter. You can use this file sg_verify.py. When you have gone through all the steps, you will see a successful connection message: Next, update the
settings.py
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/settings.py
# 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 = ' smtp.sendgrid.net'
EMAIL_HOST_USER = 'apikey'
# your unique apikey from the sendgrid website
EMAIL_HOST_PASSWORD = ' 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'
EMAIL_PORT = 587
EMAIL_USE_TLS = True
Let’s go back to http://127.0.0.1:8000/contact/, fill out and submit the form again. It works!
Retrieved 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.