As a Python developer, I’ve seen how important clean, maintainable, and user-friendly forms are in web applications. Django’s built-in forms can sometimes be a bit clunky when it comes to styling and responsiveness. That’s where Django Crispy Forms comes in.
In this article, I’ll walk you through how to create forms using Django Crispy Forms. Whether you’re building a contact form, a user registration form, or any data collection form, this guide will help you make it look professional with minimal effort.
Let’s get in!
What are Django Crispy Forms?
Django Crispy Forms is a third-party package that helps you control the rendering behavior of Django forms using Python code instead of writing HTML manually. It integrates seamlessly with popular CSS frameworks like Bootstrap, making your forms responsive and visually appealing.
From my experience, using Crispy Forms saves tons of time and reduces boilerplate code. Plus, it keeps your templates clean and easy to maintain.
Check out Calculator App in Python Django
How to Set Up Django Crispy Forms
Before we dive into code, let me show you how to set up Crispy Forms in your Django project.
Step 1: Install Django Crispy Forms
Open your terminal and run:
pip install django-crispy-formsStep 2: Add to Installed Apps
In your settings.py, add 'crispy_forms' to your INSTALLED_APPS list:
INSTALLED_APPS = [
# other apps
'crispy_forms',
]Step 3: Configure Crispy Template Pack
Still in settings.py, set the template pack to Bootstrap 4 or 5 (Bootstrap 5 is recommended for new projects):
CRISPY_TEMPLATE_PACK = 'bootstrap5'I executed the above example code and added the screenshot below.

Read To-Do List in Python Django
Create a Simple Contact Form Using Django Crispy Forms
Let me show you a real-world example — a contact form for a small USA-based business website.
Step 1: Define Your Form
Create a new file forms.py in your app directory and add:
from django import forms
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Submit
class ContactForm(forms.Form):
name = forms.CharField(max_length=100, label='Full Name')
email = forms.EmailField(label='Email Address')
message = forms.CharField(widget=forms.Textarea, label='Your Message')
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.form_method = 'post'
self.helper.add_input(Submit('submit', 'Send Message'))Here, the FormHelper class from Crispy Forms lets us control how the form renders. We set the form method to POST and add a submit button labeled “Send Message.”
Step 2: Create a View to Handle the Form
In your views.py:
from django.shortcuts import render, redirect
from .forms import ContactForm
def contact_view(request):
if request.method == 'POST':
form = ContactForm(request.POST)
if form.is_valid():
# Process form data here (e.g., send email or save to DB)
# For this example, let's just redirect to a thank you page
return redirect('thank_you')
else:
form = ContactForm()
return render(request, 'contact.html', {'form': form})Step 3: Create the Template
Create a contact.html file inside your templates directory:
{% load crispy_forms_tags %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<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>
<form method="post" novalidate>
{% csrf_token %}
{{ form|crispy }}
</form>
</div>
</body>
</html>The {{ form|crispy }} tag is what renders the form with all the Bootstrap styling automatically.
Step 4: Add URL Pattern
In your app’s urls.py:
from django.urls import path
from .views import contact_view
urlpatterns = [
path('contact/', contact_view, name='contact'),
path('thank-you/', TemplateView.as_view(template_name='thank_you.html'), name='thank_you'),
]I executed the above example code and added the screenshot below.

Create a simple thank_you.html template to confirm form submission.
Check out Get HTML Code from Rich Text in Python Django
Alternative Method: Using ModelForm with Crispy Forms
If you want to create forms tied to Django models, Crispy Forms works perfectly with ModelForm as well.
Here’s how I usually do it:
Step 1: Define a Model
from django.db import models
class CustomerInquiry(models.Model):
name = models.CharField(max_length=100)
email = models.EmailField()
message = models.TextField()
submitted_at = models.DateTimeField(auto_now_add=True)Step 2: Create a ModelForm
from django import forms
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Submit
from .models import CustomerInquiry
class CustomerInquiryForm(forms.ModelForm):
class Meta:
model = CustomerInquiry
fields = ['name', 'email', 'message']
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.form_method = 'post'
self.helper.add_input(Submit('submit', 'Submit Inquiry'))Step 3: Use the Form in Views and Templates
The process is the same as the manual form example above: instantiate the form, validate, save, and render with {{ form|crispy }}.
This method is great when you want to save form data directly to your database without extra manual handling.
Read Create an Email Sender App in Django
Tips from My Experience
- Always use
CRISPY_TEMPLATE_PACK = 'bootstrap5'for modern Bootstrap styling. - Use the
FormHelperto customize buttons, form tags, and layouts. - If you want custom layouts (like grouping fields horizontally or adding HTML elements), Crispy Forms supports that with layout objects like
Row,Column, andDiv. - Remember to include
{% load crispy_forms_tags %}at the top of your templates. - For large forms, split them into smaller sub-forms or use tabs for better UX.
Creating forms with Django Crispy Forms has significantly simplified how I build and style forms in Django projects. It saves time, reduces errors, and produces professional results without wrestling with HTML.
If you’re working on a Django project and want your forms to look good and behave responsively, give Crispy Forms a try. It’s a small addition that makes a big difference.
If you want to dive deeper, the official documentation and community examples are excellent resources to explore more advanced features.
You may read:

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.