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 contactAdd 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_USERImportant: 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
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 likepython-decoupleor 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.
- Add a Dropdown Navbar in Django
- Run Python Function by Clicking on HTML Button in Django
- Python Django Search With Dropdown Filter

I am Bijay Kumar, a Microsoft MVP in SharePoint. Apart from SharePoint, I started working on Python, Machine learning, and artificial intelligence for the last 5 years. During this time I got expertise in various Python libraries also like Tkinter, Pandas, NumPy, Turtle, Django, Matplotlib, Tensorflow, Scipy, Scikit-Learn, etc… for various clients in the United States, Canada, the United Kingdom, Australia, New Zealand, etc. Check out my profile.