Learn to create visually appealing and responsive forms in Django using crispy forms and Bootstrap 5. Simplify layouts and save time.
How to Create Forms in Django Using Crispy Forms and Bootstrap 5
Django provides an excellent way to manage forms, but making them visually appealing often requires additional work. django-crispy-forms
simplifies this process by integrating seamlessly with Bootstrap 5, allowing you to build beautiful and responsive forms effortlessly.
In this guide, I will show you how to use crispy forms to create a form in Django. This will include various field types such as input, textarea, select, checkbox, and file upload. We will also organize the fields into a responsive layout with rows and columns.
Why Use Crispy Forms?
Crispy forms offer several advantages:
- Cleaner Templates: You can define your form's layout and styling in Python, which reduces the need for repetitive HTML in your templates.
- Bootstrap Integration: Out-of-the-box support for Bootstrap 5 ensures your forms look polished and responsive.
- Reusable Helpers: Form helpers allow you to centralize styling and behavior, making your code more maintainable.
Setting Up Crispy Forms
To start, install the required packages:
pip install django-crispy-forms crispy-bootstrap5
Next, update your settings.py
file:
INSTALLED_APPS = [
# Other apps...
'crispy_forms',
'crispy_bootstrap5',
]
CRISPY_ALLOWED_TEMPLATE_PACKS = "bootstrap5"
CRISPY_TEMPLATE_PACK = "bootstrap5"
Creating the Model
Let's define a model to represent the data for our form:
from django.db import models
class ExampleModel(models.Model):
name = models.CharField(max_length=100)
description = models.TextField()
category = models.CharField(
max_length=50,
choices=[('A', 'Category A'), ('B', 'Category B'), ('C', 'Category C')]
)
agree_to_terms = models.BooleanField()
file_upload = models.FileField(upload_to='uploads/')
def __str__(self):
return self.name
This model includes various field types: CharField
for input, TextField
for textarea, CharField
with choices for a dropdown, BooleanField
for a checkbox, and FileField
for file upload.
Creating the Form
Now, let's create a form using Django's ModelForm
and integrate crispy forms with a layout helper. To do that we can define a property called helper
in our form using the @property
decorator.
from django import forms
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Layout, Row, Column, Submit
from .models import ExampleModel
class ExampleForm(forms.ModelForm):
class Meta:
model = ExampleModel
fields = ['name', 'description', 'category', 'agree_to_terms', 'file_upload']
@property
def helper(self):
helper = FormHelper()
helper.form_method = 'post'
helper.layout = Layout(
Row(
Column('name', css_class='col-md-6'),
Column('category', css_class='col-md-6'),
),
'description',
Row(
Column('file_upload', css_class='col-md-6'),
Column('agree_to_terms', css_class='col-md-6'),
),
Submit('submit', 'Submit', css_class='btn-primary')
)
return helper
The @property
decorator allows us to define a reusable helper for the form. This helper sets up the form method and organizes fields into a Bootstrap layout with rows and columns.
Rendering the Form in a Template
To render the form in a template, use the crispy forms tag. Create a new HTML file, for example, example_form.html
:
{% load crispy_forms_tags %}
<form method="post" enctype="multipart/form-data">
{% csrf_token %} {% crispy form %}
</form>
This template will automatically apply the Bootstrap 5 styling and layout defined in the form helper.
Styling Forms with Custom CSS
While django-crispy-forms
provides a sufficient default styling with Bootstrap 5, there may be times when you want to add your own custom styles. You can still use crispy forms' helper for layout and structure while applying your CSS to achieve a unique look.
Here’s how you can add custom styling to a form:
Step 1: Add Custom CSS Classes in the Form
In the form definition, you can add custom CSS classes to individual fields using the FormHelper
object:
from django import forms
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Layout, Row, Column, Submit, Field
from .models import ExampleModel
class StyledExampleForm(forms.ModelForm):
class Meta:
model = ExampleModel
fields = ['name', 'description', 'category', 'agree_to_terms', 'file_upload']
@property
def helper(self):
helper = FormHelper()
helper.form_method = 'post'
helper.layout = Layout(
Row(
Column(Field('name', css_class='custom-input-class'), css_class='col-md-6'),
Column(Field('category', css_class='custom-select-class'), css_class='col-md-6'),
),
Field('description', css_class='custom-textarea-class'),
Row(
Column(Field('file_upload', css_class='custom-file-class'), css_class='col-md-6'),
Column(Field('agree_to_terms', css_class='custom-checkbox-class'), css_class='col-md-6'),
),
Submit('submit', 'Submit', css_class='custom-submit-class')
)
return helper
Here, Field
is used to wrap each form field, allowing you to add custom CSS classes to it.
Step 2: Write Custom CSS
Now that you’ve added custom classes to the form fields, you can define styles in your CSS file. Create or update a CSS file in your Django app’s static directory. For example:
static/css/custom_form_styles.css
.custom-input-class {
border: 2px solid #007bff;
border-radius: 5px;
padding: 10px;
font-size: 16px;
}
.custom-select-class {
background-color: #f8f9fa;
border: 1px solid #ced4da;
border-radius: 5px;
padding: 8px;
}
.custom-textarea-class {
border: 2px dashed #6c757d;
border-radius: 5px;
padding: 12px;
font-size: 14px;
}
.custom-file-class {
border: 2px dotted #28a745;
padding: 8px;
border-radius: 5px;
color: #28a745;
}
.custom-checkbox-class {
margin-top: 10px;
transform: scale(1.2);
}
.custom-submit-class {
background-color: #007bff;
color: white;
border: none;
border-radius: 5px;
padding: 10px 20px;
font-size: 16px;
cursor: pointer;
}
.custom-submit-class:hover {
background-color: #0056b3;
}
Step 3: Load the CSS File in the Template
To apply your custom styles, include the CSS file in your template. Make sure the STATICFILES_DIRS
and STATIC_URL
are correctly set up in your Django project.
In your template:
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!-- Import your custom css file here -->
<link rel="stylesheet" href="{% static 'css/custom_form_styles.css' %}" />
<title>Styled Form</title>
</head>
<body>
<form method="post" enctype="multipart/form-data">
{% csrf_token %} {{ form|crispy }}
</form>
</body>
</html>
With this setup, your form fields will now have the custom styles applied. This approach allows you to use the power of crispy forms for layout and responsiveness while applying your unique design elements to the forms.
Final Thoughts
Using django-crispy-forms
with Bootstrap 5 is a very easy and fast way for creating forms in Django. It simplifies layout management, makes your templates cleaner, and ensures your forms are responsive and visually appealing. While there are some minor limitations, such as dependency on specific Bootstrap versions, the benefits make it a must-have tool for most of your Django projects.
Whether you're building a simple contact form or a more complex data entry system, crispy forms can save you time and effort while delivering professional-looking results.