crispy-bootstrap4
crispy-bootstrap4 is a template pack for django-crispy-forms, providing Bootstrap 4 styling for Django forms. It facilitates rendering forms elegantly without extensive manual HTML, offering control over layout and appearance. The library is actively maintained, with a version 2026.2 released on February 11, 2026, and follows a frequent release cadence, often coinciding with Django and Python version updates.
Warnings
- breaking Support for several Django versions has been removed in recent releases. Version 2026.2 dropped support for Django 4.2, 5.0, and 5.1. Version 2023.1 previously dropped Django 3.2, 4.0, and 4.1.
- breaking Support for `django-crispy-forms` 1.x was dropped in version 2023.1, and the minimum supported version was bumped to 2.3 in 2024.10.
- gotcha When adding to `INSTALLED_APPS` in `settings.py`, use the Python package name with an underscore: `crispy_bootstrap4`. Using the PyPI package name with a hyphen (`crispy-bootstrap4`) will result in an `ModuleNotFoundError`.
- gotcha This template pack does not include Bootstrap 4's CSS or JavaScript assets. You must manually link to Bootstrap 4's CSS and JS files in your Django templates (e.g., via CDN or local static files) for forms to render with the correct styling.
- gotcha The `id` attribute for help text generated by forms changed in version 2025.6 to align with the `aria-describedby` attribute added by Django 5.0+. This might impact custom JavaScript or CSS that relied on the previous help text `id` structure.
Install
-
pip install crispy-bootstrap4
Imports
- crispy_forms
INSTALLED_APPS = [ # ... 'crispy_forms', 'crispy_bootstrap4', ] - CRISPY_TEMPLATE_PACK
CRISPY_TEMPLATE_PACK = 'bootstrap4'
Quickstart
# settings.py
INSTALLED_APPS = [
# ... other Django apps
'crispy_forms',
'crispy_bootstrap4',
]
CRISPY_ALLOWED_TEMPLATE_PACKS = 'bootstrap4'
CRISPY_TEMPLATE_PACK = 'bootstrap4'
# my_app/forms.py
from django import forms
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Layout, Submit
class ContactForm(forms.Form):
name = forms.CharField(label='Your Name')
email = forms.EmailField(label='Your Email')
message = forms.CharField(widget=forms.Textarea, label='Your Message')
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.layout = Layout(
'name',
'email',
'message',
Submit('submit', 'Send Message', css_class='btn-primary')
)
# my_app/templates/my_app/contact.html
{% load crispy_forms_tags %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Contact Us</title>
<!-- Include Bootstrap 4 CSS and JS manually -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
</head>
<body>
<div class="container">
<h1>Contact Us</h1>
<form method="post">
{% csrf_token %}
{% crispy form %}
</form>
</div>
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
</body>
</html>