How to Build a Django Contact Form with Email Functionality

While working with Python data frames for one of my clients, I was supposed to build a simple web dashboard to showcase dynamic analytics. As part of the deliverable, the client requested a way for users, primarily internal analysts and external partners, to get in touch directly from the dashboard.

The requirement was to embed a contact form into the dashboard itself, where users could submit queries, bug reports, or feature requests. In this tutorial, I’ll walk you through how to build a Django contact form that sends emails, step by step.

Steps to Build a Contact Form in Django

A contact form is often the first point of communication between your website visitors and you. For businesses in the USA, having an easy way for customers to reach out is crucial for building trust and generating leads.

Django, with its useful form handling and email backend, makes it easy to create such a form without relying on third-party services. Plus, you get full control over the data and the user experience.

Read Django CRUD with Bootstrap Template

Step 1: Set Up Your Django Project and App

First, create a new Django project and app if you haven’t already.

django-admin startproject mysite
cd mysite
python manage.py startapp contact

Add the contact app to your INSTALLED_APPS in mysite/settings.py:

INSTALLED_APPS = [
    # other apps
    'contact',
]

Step 2: Configure Email Settings

To send emails, Django needs to know your email server settings. For this example, I’ll use Gmail’s SMTP server, which is common for many small businesses in the USA.

Add the following to your settings.py:

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_PORT = 587
EMAIL_USE_TLS = True
EMAIL_HOST_USER = 'your-email@gmail.com'  # Replace with your email
EMAIL_HOST_PASSWORD = 'your-email-password'  # Use app-specific password if 2FA enabled
DEFAULT_FROM_EMAIL = EMAIL_HOST_USER

Important: For security, don’t hardcode your credentials in production. Use environment variables or a secrets manager.

Check out Delete Session Property in Django

Step 3: Create the Contact Form

In your contact app, create a forms.py file:

from django import forms

class ContactForm(forms.Form):
    name = forms.CharField(max_length=100, widget=forms.TextInput(attrs={'placeholder': 'Your Name'}))
    email = forms.EmailField(widget=forms.EmailInput(attrs={'placeholder': 'Your Email'}))
    subject = forms.CharField(max_length=150, widget=forms.TextInput(attrs={'placeholder': 'Subject'}))
    message = forms.CharField(widget=forms.Textarea(attrs={'placeholder': 'Your Message'}))

This form collects the visitor’s name, email, subject, and message.

Step 4: Create Views to Handle the Form

In contact/views.py, add the following:

from django.shortcuts import render, redirect
from django.core.mail import send_mail, BadHeaderError
from django.http import HttpResponse
from .forms import ContactForm

def contact_view(request):
    if request.method == 'POST':
        form = ContactForm(request.POST)
        if form.is_valid():
            name = form.cleaned_data['name']
            email = form.cleaned_data['email']
            subject = form.cleaned_data['subject']
            message = form.cleaned_data['message']
            full_message = f"Message from {name} <{email}>:\n\n{message}"
            try:
                send_mail(subject, full_message, email, ['your-business-email@example.com'])
            except BadHeaderError:
                return HttpResponse('Invalid header found.')
            return redirect('contact_success')
    else:
        form = ContactForm()
    return render(request, 'contact/contact.html', {'form': form})

def contact_success(request):
    return render(request, 'contact/success.html')

Explanation:

  • We check if the request method is POST.
  • Validate the form data.
  • Compose an email with the visitor’s message.
  • Send the email to your business email.
  • Redirect to a success page if the email sends successfully.

Read AttributeError: Module Object has no Attribute in Django

Step 5: Create Templates for the Form and Success Page

Create a folder templates/contact/ inside your contact app directory.

contact.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Contact Us</title>
    <style>
        body { font-family: Arial, sans-serif; margin: 40px; }
        form { max-width: 600px; margin: auto; }
        input, textarea { width: 100%; padding: 10px; margin: 10px 0; }
        button { padding: 10px 20px; background-color: #0073e6; color: white; border: none; }
        button:hover { background-color: #005bb5; }
    </style>
</head>
<body>
    <h1>Contact Us</h1>
    <form method="post" novalidate>
        {% csrf_token %}
        {{ form.as_p }}
        <button type="submit">Send</button>
    </form>
</body>
</html>

success.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Message Sent</title>
    <style>
        body { font-family: Arial, sans-serif; margin: 40px; text-align: center; }
        a { color: #0073e6; text-decoration: none; }
    </style>
</head>
<body>
    <h1>Thank You!</h1>
    <p>Your message has been sent successfully. We will get back to you shortly.</p>
    <a href="{% url 'contact' %}">Send another message</a>
</body>
</html>

Step 6: Configure URLs

In contact/urls.py, add:

from django.urls import path
from .views import contact_view, contact_success

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

Then include this in your main mysite/urls.py:

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

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

Check out Get User IP Address in Django

Step 7: Test Your Contact Form

Run your server:

python manage.py runserver
django contact form

Navigate to http://127.0.0.1:8000/contact/ and try sending a message. If everything is configured correctly, you should receive the email at your business email address.

Read Parse CSV in Python Django

Additional Tips from My Experience

  • Use Environment Variables: Never store email credentials in plain text inside settings.py. Use packages like python-decouple or environment variables.
  • Add CAPTCHA: To avoid spam, consider integrating Google reCAPTCHA.
  • Customize Email Templates: For a more professional look, use HTML email templates.
  • Error Handling: Add user-friendly error messages for email sending failures.
  • Logging: Log email sending status for troubleshooting.

Building a contact form with email functionality in Django is a common but essential feature that every developer should know how to implement. With this setup, you have a solid foundation that you can expand with features like file attachments, multiple recipients, or even saving inquiries to your database.

I hope you found this tutorial easy and practical. Customize the form fields and email content to suit your business needs.

You may also like to read other Django articles.

51 Python Programs

51 PYTHON PROGRAMS PDF FREE

Download a FREE PDF (112 Pages) Containing 51 Useful Python Programs.

pyython developer roadmap

Aspiring to be a Python developer?

Download a FREE PDF on how to become a Python developer.

Let’s be friends

Be the first to know about sales and special discounts.