Build a Contact Form in Django Using Bootstrap

I’ve built many forms, but integrating Django with Bootstrap has always been my go-to approach for clean, responsive, and user-friendly forms. If you want to create a sleek contact form for your Django app that looks great on all devices, you’re in the right place.

In this tutorial, I’ll walk you through how to build a fully functional contact form in Django using Bootstrap. I’ll share complete code examples and explain each step clearly so you can follow along easily, even if you’re just starting with Django or Bootstrap.

Methods to Build a Contact Form in Django Using Bootstrap

Now, I will explain to you the methods to build a contact Form in Django using Bootstrap.

Read Django Programming Error: Column does not exist.

Method 1: Build a Basic Contact Form with Django Forms and Bootstrap

Step 1: Set Up Your Django Project and App

If you haven’t already created a Django project, run:

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

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

INSTALLED_APPS = [
    # other apps
    'contact',
]

Step 2: Create the Contact Form Using Django’s forms.Form

In contact/forms.py, define your contact form fields:

from django import forms

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

Here, I added Bootstrap classes directly to the widgets to ensure the form looks good without extra CSS.

Step 3: Create the View to Handle the Form

In contact/views.py:

from django.shortcuts import render, redirect
from django.core.mail import send_mail
from .forms import ContactForm
from django.conf import settings
from django.contrib import messages

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}"

            send_mail(
                subject,
                full_message,
                settings.DEFAULT_FROM_EMAIL,
                [settings.DEFAULT_FROM_EMAIL],  # Send to your email
                fail_silently=False,
            )
            messages.success(request, 'Your message has been sent successfully!')
            return redirect('contact')
    else:
        form = ContactForm()

    return render(request, 'contact/contact.html', {'form': form})

Make sure you configure your email settings in settings.py for send_mail to work. For example, using Gmail SMTP:

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_USE_TLS = True
EMAIL_PORT = 587
EMAIL_HOST_USER = 'your_email@gmail.com'
EMAIL_HOST_PASSWORD = 'your_password'
DEFAULT_FROM_EMAIL = EMAIL_HOST_USER

Step 4: Create the Template with Bootstrap

Create a folder contact/templates/contact/ and inside it, create contact.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Contact Us</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet" />
</head>
<body>
<div class="container mt-5">
    <h2>Contact Us</h2>
    <hr>
    {% if messages %}
        {% for message in messages %}
            <div class="alert alert-success">{{ message }}</div>
        {% endfor %}
    {% endif %}

    <form method="post" novalidate>
        {% csrf_token %}
        <div class="mb-3">
            {{ form.name.label_tag }}
            {{ form.name }}
            {% for error in form.name.errors %}
                <div class="text-danger">{{ error }}</div>
            {% endfor %}
        </div>
        <div class="mb-3">
            {{ form.email.label_tag }}
            {{ form.email }}
            {% for error in form.email.errors %}
                <div class="text-danger">{{ error }}</div>
            {% endfor %}
        </div>
        <div class="mb-3">
            {{ form.subject.label_tag }}
            {{ form.subject }}
            {% for error in form.subject.errors %}
                <div class="text-danger">{{ error }}</div>
            {% endfor %}
        </div>
        <div class="mb-3">
            {{ form.message.label_tag }}
            {{ form.message }}
            {% for error in form.message.errors %}
                <div class="text-danger">{{ error }}</div>
            {% endfor %}
        </div>

        <button type="submit" class="btn btn-primary">Send Message</button>
    </form>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

Step 5: Add URL Configuration

In contact/urls.py:

from django.urls import path
from .views import contact_view

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

And include it in your project’s main urls.py:

from django.urls import path, include

urlpatterns = [
    # other paths
    path('contact/', include('contact.urls')),
]

You can see the output in the screenshot below.

django bootstrap form

Check out Integrity Error in Django

Method 2: Use Django Crispy Forms for Cleaner Bootstrap Integration

While the above method works well, manually adding Bootstrap classes to every form field can get tedious. I recommend using the Django Crispy Forms package for better maintainability.

Step 1: Install Django Crispy Forms

pip install django-crispy-forms

Add it to your INSTALLED_APPS in settings.py:

INSTALLED_APPS = [
    # other apps
    'crispy_forms',
]

CRISPY_TEMPLATE_PACK = 'bootstrap5'

Step 2: Update Your Form

In forms.py, remove the manual widget classes:

from django import forms

class ContactForm(forms.Form):
    name = forms.CharField(max_length=100)
    email = forms.EmailField()
    subject = forms.CharField(max_length=200)
    message = forms.CharField(widget=forms.Textarea)

Step 3: Update Your Template

Modify contact.html to use Crispy Forms tags:

{% load crispy_forms_tags %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Contact Us</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet" />
</head>
<body>
<div class="container mt-5">
    <h2>Contact Us</h2>
    <hr>
    {% if messages %}
        {% for message in messages %}
            <div class="alert alert-success">{{ message }}</div>
        {% endfor %}
    {% endif %}

    <form method="post" novalidate>
        {% csrf_token %}
        {{ form|crispy }}
        <button type="submit" class="btn btn-primary">Send Message</button>
    </form>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

You can see the output in the screenshot below.

django bootstrap form

This will automatically render your form fields with Bootstrap 5 styles without manually adding CSS classes.

Read Python Django “Template does not exist” error

Tips for Production Use

  • Always validate user input carefully.
  • Use Django’s built-in security features like CSRF tokens (already included in the example).
  • Configure your email backend securely. For production, avoid storing email passwords directly in settings.py use environment variables or secret managers.
  • Consider adding CAPTCHA to prevent spam submissions.
  • Customize your success and error messages for a better user experience.

Building a contact form in Django using Bootstrap doesn’t have to be complicated. Whether you prefer the manual approach or leveraging Django Crispy Forms, both methods help you create responsive, clean forms quickly.

Try implementing this in your next Django project and enjoy the seamless integration of backend power with frontend elegance.

You may also read:

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.