Build a Django Contact Form with Email

In this Python Django tutorial, I will explain how to build a Django contact form with email backend step by step.

While working on a contact form using HTML, I just found out that creating a contact form that sends an email using HTML required dozens of lines of code and a lot of work.

So, I have done the research and discovered that Django offers form classes. Here we will focus on rendering a Django form using ModelForm class.

Here we will see:

  • When to need email backend
  • How to build a Django contact form with email and send emails to your Gmail account.
  • How to save form data to an in-built Django database
  • How to view submitted data in Django
  • How to use various controls like textbox, textarea, email, and radio buttons in Django
  • How to render the form as a table in Django
  • How to Setup Email Authentication in Gmail

This is what we will build here.

Python Django build a contact form with email
Contact Form

At the end of this article, you can also download the code: Build a Django Contact Form with Email.

Build a Django Contact Form with Email

Now, let us see, step by step how Django sends an email on contact form submission.

Email Backend

Sometimes, you have noticed that the moment we submit the contact form we instantly got the revert mail from the website. Now the question arises how this thing will happen?

Basically, the contact form is connected to the email backend which automatically works and sends an email each time when the form is submitted to the user on the behalf of the website staff.

In simple words, you can say that by using the email with the contact form the autogenerated email is sent to the user.

Read: How to install Django

Setup Django Project

Firstly, we need to establish a project in Django using the below-given command. Here TrainingGuides is the name of the project.

django-admin startproject TrainingGuides

Create a Django app named Contact, within the Django project, by typing the below command in the terminal.

python manage.py startapp Contact

Add the Contact app to the INSTALLED_APPS list located in the settings.py file.

build a contact form with email
settings.py

A file named urls.py is automatically included by Django in the project directory. Inside it, maps the recently created app Contact as given below.

from django.contrib import admin
from django.urls import path,include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('',include('Contact.urls')),
]

Read: How to create web form in Python Django

Create Model

To create models in Django open the models.py file inside the app directory and add the below-given code.

from django.db import models

# Create your models here.

class Contact(models.Model):
    name = models.CharField(max_length=250)
    email = models.EmailField()
    phone = models.CharField(max_length=10)
    mode_of_contact = models.CharField('Conatct by', max_length=50)
    question_categories = models.CharField('How can we help you?', max_length=50)
    message = models.TextField(max_length=3000)

    def __str__(self):
        return self.email

Here, we create a model class Contact which has the following fields.

  1. The name is Django CharFields. And there is a 25-character limit for this character field.
  2. The email is Django EmailField which allows users to save email addresses.
  3. The phone is Django CharField. And there is a 10-character limit for this character field.
  4. The mode_of_contact and question_categories are Django CharField. And there is a 50-character limit for these character fields. 
  5. The message field is Django TextField. And there is a 3000-character limit for it.

And to change the display name of the object in the Django model use the def __str__(self). It will render the item name as email as we return the self.email.

To register the Contact model with the admin site, open the admin.py file and add the below-given code.

from django.contrib import admin
from .models import Contact

# Register your models here.

admin.site.register(Contact)

Read: Python Django vs Pyramid

Create Django Form with various fields

Create the Django form that the Contact application will use to collect user input. Add the following code to the forms.py file you create inside the app directory.

from django import forms
from .models import Contact

select_mode_of_contact = (
    ("email", "E-Mail"),
    ("phone", "Phone"),
)

select_question_categories = (
    ("certification", "Certification"),
    ("interview", "Interview"),
    ("material", "Material"),
    ("access_duration","Access and Duration"),
    ("other", "Others"),
)

class ContactForm(forms.ModelForm):
    phone = forms.CharField(required=False)
    mode_of_contact = forms.CharField(required=False, widget=forms.RadioSelect(choices=select_mode_of_contact))
    question_categories = forms.CharField(required=False, widget=forms.Select(choices=select_question_categories))

    class Meta:
        model = Contact
        fields = '__all__'
  • Here, we define a form class called ContactForm that has all the fields from the Contact model.
  • Additionally, the mode_of_contact and question_categories are Django CharField. There is a choices option that are sequences that may be used as options for a field and consists of iterables for items.
  • And we define a tuple for this named select_question_categories and select_mode_of_contact.

Render the form as a table in Django

Create a subdirectory called Templates in the main project directory to store all of the project templates since the front end of a Django application is defined in Templates.

Open the settings.py file, and update the DIRS to refer to the Templates folder’s location.

Django create a contact form and send emails to your Gmail account
settings.py

To define the front end of the contact form that sends emails, create an HTML file named contact.html inside the Templates folder and include the code given below.

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Contact</title>
</head>

<body>
    <div style="margin:80px">
        <h1 align="center">Contact Us</h1>
        <hr>
        <h4>Contact us directly if you have any queries. We will get in touch with you shortly.</h4>
        <hr>
        <br>
        <form method="post" action="" enctype="multipart/form-data" class="post-form">
            {% csrf_token %}
            <table>
                {{form.as_table}}
            </table>
            <button type="submit" class="save btn btn-default">Submit</button>
        </form>
</body>

</html>
  • Use the HTML tags h1 and h4 to add the heading to the form.
  • The form will then be posted once it has been submitted by calling the form tag with the POST method.
  • Add the csrf_token within the form element to protect the form from cyberattacks and enable us to deliver the data securely.
  • Next, use the form.as_table tag within the table tag to render the form as a paragraph.
  • Add a Submit button to the form to complete it.

We want to render the contact form to another page when it is successfully submitted, so we receive the success message and the contact form link.

To do this, we add another HTML file called success.html to the Template Folder.

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Success</title>
</head>

<body>
    <h2 style="text-align: center; color: red;" "></h2style>We sent your message</h2>
    <p> You can send another in the <a href=" {% url 'contact' %}">Contact Page</a></p>
</body>

</html>

The h2 tag is used to define the heading, and the text-align and color attributes are used to center the text, align it, and change its color to red. Then, within the p tag, we utilize the a href tag to link it to the contact form.

Read: Python Django vs ReactJS

Define View in Django

The logic of the program is placed in a Python function called a Django view, which then responds to the user.

Open the views.py file and add the code provided below to create the core logic for the contact form with email setup.

from django.shortcuts import render
from .forms import ContactForm
from django.core.mail import send_mail
from django.conf import settings

# Create your views here.

def contact(request):
    if request.method == 'POST':
        form = ContactForm(request.POST)
        if form.is_valid(): 
            form.save()
            subject = "Welcome to PythonGuides Training Course"
            message = "Our team will contact you within 24hrs."
            email_from = settings.EMAIL_HOST_USER
            email = form.cleaned_data['email']
            recipient_list =email
            send_mail(subject, message, email_from, [recipient_list])
            return render(request, 'success.html') 
    form = ContactForm()
    context = {'form': form}
    return render(request, 'contact.html', context)
  • First import the ContactForm from the forms.py, then call the if statement and check whether the request method is POST.
  • If yes, we pass ContactForm(request.POST) that binds the data to the form class, so we can do validation.
  • Now, call the is_valid() to validate the input entered by the user, and if validation success saves the form data using save().
  • If the request method is GET, the user is presented with a blank contact form using the render() function.

Setup Email Authentication in Gmail

Here we use Gmail for sending emails so we have to set up an app password,

If we don’t set an app password we will receive SMTPAuthenticationError. This error occurs because Django lacks the ability to adhere to Google’s security standards.

Follow the below steps to set up of password.

  • Log in to Gmail and go to the settings for your inbox and click on See all settings.
django contact form with email
Gmail Settings
  • Then navigate Account and Import.
python django contact form with email
Account and Import
  • Navigate to Other Google Account settings.
contact form with email using django
Account Settings
  • Then, click on security.
django contact form using email
Gmail Security
  • Set up security checkup settings and enable 2-step factor verification.
django python contact form with email
2-Step Verification
  • After that, Enable IMAP under the Forwarding and POP/IMAP settings. And please remember to save your settings.
contact form in pythonn django with email
POP/IMAP
  • Once we have ensured that IMAP and the 2-factor are both enabled. Navigate back to the settings page for your Google Account and select the Security option.
django contact form with email
Security
  • Once there, move the cursor down a bit and select the App Passwords option.
image
App Password
  • Once we’ve done this, pick Other under Select Device after clicking through. Name this password whatever we want and once you name the app password, click Generate.
django contact form example with email
Other Device

If everything went well, a page displaying your app password would have shown.

python django contact form example with email
App Password

Read: Python Django form validation

Views for Email Setup in Django

Additionally, the website staff notifies the user via email each time the contact form is submitted 

Open the settings.py file and add the following code to add the settings needed for Django to send emails.

# Email Settings

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_USE_TLS = True
EMAIL_PORT = 587
EMAIL_HOST_USER = #sender email-id
EMAIL_HOST_PASSWORD = #password associated with sender email-id

The following are the detailed descriptions of the options that we use above.

  • EMAIL_BACKEND:
    • The backend that our Django project will use to connect to the SMTP server is specified by the EMAIL_BACKEND parameter.
    • The smtp is the target of this variable and EmailBackend class receives all the email-sending parameters.
  • EMAIL_HOST:
    • The SMTP server domain you’ll be utilizing is indicated by the EMAIL_HOST option. Your email service provider will decide this. As here Gmail is the email provider so we set the SMTP server host to smtp.gamil.com.
    • If you are using Yahoo as an email provider set its SMTP server host to smtp.mail.yahoo.com and if you are using Outlook as an email provider set its SMTP server to smtp-mail.outlook.com.
  • EMAIL_USE_TLS:
    • A security protocol called TLS is used on the Internet to encrypt communication between Django and SMTP servers.
    • The EMAIL_USE_TLS option was set to True to indicate that Django will connect to the SMTP server and send emails using Transport Layer Security.
  • EMAIL_PORT:
    • The default port for the majority of SMTP servers is 587, so the EMAIL_PORT parameter must be set to that value.
  • EMAIL_HOST_USER:
    • The EMAIL_HOST_USER is the email address of the website staff.
  • EMAIL_HOST_PASSWORD:
    • The EMAIL_HOST_PASSWORD is the password credential of the website staff email.

Code for Contact form with email setup.

from django.shortcuts import render
from .forms import ContactForm
from django.core.mail import send_mail
from django.conf import settings

# Create your views here.

def contact(request):
    if request.method == 'POST':
        form = ContactForm(request.POST)
        if form.is_valid(): 
            form.save()
            subject = "Welcome to PythonGuides Training Course"
            message = "Our team will contact you within 24hrs."
            email_from = settings.EMAIL_HOST_USER
            email = form.cleaned_data['email']
            recipient_list =email
            send_mail(subject, message, email_from, [recipient_list])
            return render(request, 'success.html') 
    form = ContactForm()
    context = {'form': form}
    return render(request, 'contact.html', context)
  • Import the Django send_mail function as well as the settings variable, which holds all of the global options contained in the settings.py file.
  • Then, pass all the arguments require while composing an email to the send_mail(), which handles email sending in Django.
  • The following are the arguments that you pass to the function.
    • subject: It specifies the e-mail subject.
    • message: It specifies the message that you pass to the user. In short, it is the body of the email.
    • email_from: It specifies the sender’s details. Set its value to settings.EMAIL_HOST_USER as it takes value from there.
    • recipient_list: It specifies the receiver details. It is always in the list form and set its value to email as all the users who have submitted the contact form receive the email.

Read: Python Django app upload files

Execute Application in Django

We must first make a migration for the given model in order to start using it. Run the following command through the terminal.

python manage.py makemigartions

To reflect it, we must migrate the database. The migrate command is listed below.

python manage.py migrate

To start a development server for this particular Django project, we enter the command below into the terminal.

python manage.py runserver

By expanding the URL as shown below, we can access the contact form.

127.1.1.0/contact

It successfully opens the Django contact form with the email backend which looks like this.

Python Django build a contact form with email
Contact Form with Email Backend

Now, fill out the contact form and click the submit button as shown below.

Python Django simple contact form with email
Contact form with details

After clicking on submit, it will move to the success page. And if we click on the Contact Page link, we will again redirect to a blank contact form.

Django create a contact form with email
Success Page

Additionally, a user’s email that they provided in the form will receive an email from the website owner after they hit the submit button.

Python Django form send email
User Email
Django contact form and email send to Gmail
Website Owner Email

Read: Python Django MySQL CRUD

View submitted data from the Django admin interface

It will also save the data in the database. If you want to view it, create a superuser and open the admin application and view it.

python django contact form and email to gmail
Admin Interface

This is how we can render a Django contact form and send emails to the user from Gmail.

Read: Django CRUD example with PostgreSQL

Download the Django Contact Form with Email complete code

Here is the code.

Conclusion

With this, we have successfully created a working Django form with Django ModelForm class that also makes use of a database. We have also learned how to send automatic emails from the website owner to users who have filled out the form.

Additionally, we have also covered the following topics.

  • When to need email backend
  • How to build a Django contact form with email and send emails to your Gmail account.
  • How to save form data to an in-built Django database
  • How to view submitted data in Django
  • How to use various controls like textbox, textarea, email, and radio buttons in Django
  • How to render the form as a table in Django

You may also like to read the following Python Django Tutorials.