Integrating django-crispy-forms with TailwindCSS
In this post, we'll walk you through the process of integrating django-crispy-forms
with TailwindCSS
using the crispy-tailwind
package. We'll create a small Contact Form to showcase this powerful combination.
Objectives
In this post, we'll learn how to:
- Create a Django form class and add it to our webpage
- Style up the form using
django-crispy-forms
andTailwindCSS
- using thecrispy-tailwind
template pack - Create custom layouts with
django-crispy-forms
Introduction
Before we dive in, let's briefly touch on what Tailwind
and django-crispy-forms
are:
- TailwindCSS is a utility-first CSS framework that allows for rapid custom designs.
- django-crispy-forms is a Django app that lets you easily build, customize and reuse forms using your favourite CSS framework.
django-crispy-forms uses Template Packs to style forms. We'll be using the crispy-tailwind
template pack in this tutorial, which is a template pack designed for TailwindCSS.
We're going to start by creating a normal Django form, and will enhance this form using Tailwind as the video progresses.
Step 1: Creating a Django Form
Let's start by creating a simple Contact Form in Django. Create a file named forms.py
in your Django app and add the following code:
from django import forms
class ContactForm(forms.Form):
REASON_CHOICES = [
('', 'Select a reason'),
('general', 'General Inquiry'),
('support', 'Technical Support'),
('feedback', 'Feedback'),
('other', 'Other'),
]
name = forms.CharField(label='Your Name', max_length=100, required=True)
email = forms.EmailField(label='Your Email', required=True)
reason = forms.ChoiceField(label='Reason for Contact', choices=REASON_CHOICES, required=True)
subject = forms.CharField(label='Subject', max_length=200, required=False)
message = forms.CharField(label='Your Message', widget=forms.Textarea(attrs={'rows': 4}), required=True)
subscribe = forms.BooleanField(label='Subscribe to newsletter', required=False)
Next, add the form to your view:
from core.forms import ContactForm
def index(request):
context = {'form': ContactForm()}
return render(request, 'index.html', context)
This makes the form available for use in the index.html
template. Let's add the form there.
<h1>Contact Us</h1>
<form method="POST">
{% csrf_token %}
{{ form }}
<button>Submit</button>
</form>
At this point, your form will be functional but won't look great - it should appear similar to the snippet below.
Let's improve this by adding TailwindCSS
and django-crispy-forms
!
Step 2: Installing TailwindCSS and crispy-tailwind
For this tutorial, we'll use the TailwindCSS Play CDN (not recommended for production):
Add this to your base.html
:
<script src="https://cdn.tailwindcss.com"></script>
Now, install crispy-tailwind
:
pip install crispy-tailwind
After installing, we need to add both crispy-tailwind
and django-crispy-forms
to the Django app's INSTALLED_APPS
setting. We'll also set the template pack for crispy-forms here:
INSTALLED_APPS = (
...
"crispy_forms",
"crispy_tailwind",
...
)
CRISPY_ALLOWED_TEMPLATE_PACKS = "tailwind"
CRISPY_TEMPLATE_PACK = "tailwind"
The template pack setting tells django-crispy-forms
to use TailwindCSS for styling the form fields.
Step 3: Using the Crispy Filter
In your template, load the crispy-tailwind filters and apply the crispy
filter to your form. We'll also add some TailwindCSS styles to the button in the form, as well as the container <div>
{% load tailwind_filters %}
<div class="w-full max-w-2xl mx-auto sm:px-6 lg:px-8">
<h1 class="text-4xl font-bold mb-8">Contact Us</h1>
<form method="POST">
{% csrf_token %}
{{ form|crispy }}
<button class="text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 me-2 mb-2 dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800">Submit</button>
</form>
</div>
Let's see how this looks now.
Much nicer than before!
Step 4: Advanced Customization with Crispy Forms Layouts
For more control over your form's layout, you can use Crispy Forms Layouts.
Modify your ContactForm
class and add an __init__
method that creates a FormHelper
object.
from crispy_forms.layout import Layout, Div, Submit
from crispy_forms.helper import FormHelper
class ContactForm(forms.Form):
# ... (previous form fields here)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.form_class = 'border p-8'
self.helper.layout = Layout(
Div(
Div('name', css_class="md:w-[50%]"),
Div('reason', css_class="md:w-[50%]"),
css_class="md:flex md:justify-between"
),
'email',
'subject',
'message',
'subscribe',
Submit('submit', 'Submit', css_class='text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 me-2 mb-2 dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800'),
)
Then, update your template to use the crispy
template tag, rather than the template filter.
You can also remove the <form>
and <button>
elements from your code - crispy-forms
layouts automatically generate these for you:
{% load crispy_forms_tags %}
<div class="w-full max-w-2xl mx-auto sm:px-6 lg:px-8">
<h1 class="text-4xl font-bold mb-8">Contact Us</h1>
{% crispy form %}
</div>
Let's take a look at this, with our new layout.
Because of our layout, with the Div elements, the first two fields of the form are inline, using flex classes.
We also have a border around the form - this was added on this line: self.helper.form_class = 'border p-8'
django-crispy-forms enables you to customize the form itself, as well as the submit button classes, from inside the Django Form class, using these FormHelper
and Layout
objects.
Summary
By following these steps, you've successfully integrated django-crispy-forms with TailwindCSS, creating a sleek and customizable contact form. This approach allows you to leverage the power of both frameworks, resulting in forms that are not only functional but also visually appealing.
Before we finish, remember that while this tutorial used the TailwindCSS Play CDN for simplicity, it's recommended to use a proper Tailwind setup for production environments.
If you enjoyed this post, please subscribe to our YouTube channel and follow us on Twitter to keep up with our new content!
Please also consider buying us a coffee, to encourage us to create more posts and videos!