Install & Compatibility
Where this runs
tested against v2.7 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslpy 3.10–3.910 runs
installs and imports cleanly · install 0.0s · import 0.806s · 66.8MB
glibcpy 3.10–3.910 runs
installs and imports cleanly · install 3.5s · import 0.722s · 67MB
66MB installed
● package 66MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
FormHelper
✓ from crispy_forms.helper import FormHelper
Used to programmatically define form rendering behavior.
Layout
✓ from crispy_forms.layout import Layout
Primary class for defining custom form layouts.
Submit
✓ from crispy_forms.layout import Submit
Layout object to add a submit button to your form.
Div
✓ from crispy_forms.layout import Div
Layout object to group fields within a <div> tag.
Row
✓ from crispy_forms.layout import Row
Layout object to create a Bootstrap row for multi-column layouts.
Fieldset
✓ from crispy_forms.layout import Fieldset
Layout object to group fields within a <fieldset> tag.
This quickstart demonstrates how to define a Django form with `FormHelper` and `Layout` objects to customize its appearance using `django-crispy-forms`. It includes setting up a two-column row and a submit button. Remember to add `crispy_forms` and your chosen template pack (e.g., `crispy_bootstrap5`) to `INSTALLED_APPS` and configure `CRISPY_TEMPLATE_PACK` in your `settings.py`. In your template, load `crispy_forms_tags` and render the form using `{% crispy form %}`.
import os
from django import forms
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Layout, Submit, Row, Column
# settings.py (excerpt)
# INSTALLED_APPS = [
# ...,
# 'crispy_forms',
# 'crispy_bootstrap5', # Or your chosen template pack
# ]
# CRISPY_ALLOWED_TEMPLATE_PACKS = ['bootstrap5']
# CRISPY_TEMPLATE_PACK = 'bootstrap5'
class ContactForm(forms.Form):
name = forms.CharField(label='Your Name', max_length=100)
email = forms.EmailField(label='Your Email')
message = forms.CharField(label='Your Message', widget=forms.Textarea)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.layout = Layout(
Row(
Column('name', css_class='form-group col-md-6 mb-0'),
Column('email', css_class='form-group col-md-6 mb-0'),
css_class='form-row'
),
'message',
Submit('submit', 'Send Message', css_class='btn btn-primary')
)
# views.py (excerpt)
# from django.shortcuts import render
# def contact_view(request):
# form = ContactForm()
# return render(request, 'contact.html', {'form': form})
# contact.html (excerpt)
# {% load crispy_forms_tags %}
# <form method="post">
# {% csrf_token %}
# {% crispy form %}
# </form>
# To make this runnable in a minimal context (not a full Django app)
# This part is for demonstration only and assumes Django is configured
# and settings above are set if running in a real project.
if __name__ == '__main__':
# This part is purely illustrative as it requires a full Django setup
# and request cycle to actually render.
# In a real Django app, you would define this in forms.py
# and then render in a template using `{% crispy form %}`
form_instance = ContactForm()
print("Quickstart Form Helper and Layout defined successfully.")
print("Remember to configure settings.py and your templates as per comments.")
Debug
Known issues
breakingVersion 2.0 removed all built-in Bootstrap template packs. These are now standalone packages (e.g., `crispy-bootstrap5`).fixInstall the appropriate template pack (e.g., `pip install crispy-bootstrap5`) and add it to `INSTALLED_APPS` and set `CRISPY_TEMPLATE_PACK` in your `settings.py`.
affects: >=2.0
breakingVersion 2.6 dropped support for Django 4.2, 5.0, and 5.1.fixUpgrade your Django version to a supported one (e.g., Django 5.2 or later as per 2.4 release, or 6.0 as per 2.5 release) or downgrade `django-crispy-forms` to a compatible version.
affects: >=2.6
breakingVersion 2.5 dropped support for Python 3.8. Version 2.1 dropped support for Python 3.7.fixEnsure your project uses Python 3.9 or newer for `django-crispy-forms` 2.5+, and Python 3.8 or newer for `django-crispy-forms` 2.1-2.4. Python 3.10 is the minimum requirement for 2.6.
affects: >=2.1 (Python 3.7), >=2.5 (Python 3.8)
gotchaCrispy Forms does not include static files (CSS/JS) for template packs. You must include them yourself.fixManually link the CSS and JavaScript files for your chosen CSS framework (e.g., Bootstrap) in your base templates. Refer to your CSS framework's documentation for correct setup.
affects: All versions
gotchaForm validation errors may not appear if you are using complex layout objects or specific template customizations.fixEnsure that `{{ form.errors }}` or `{{ form|as_crispy_errors }}` is included in your template to display non-field errors. For field-specific errors, ensure your layout objects are correctly structured to allow their display. affects: All versions
gotchaNot setting `CRISPY_TEMPLATE_PACK` globally may lead to forms not rendering 'crispy' by default, or with an unexpected template pack.fixAdd `CRISPY_TEMPLATE_PACK = 'your_template_pack'` (e.g., `'bootstrap5'`) to your `settings.py` to define the default template pack. You can also specify it per form or even per `{% crispy %}` tag. affects: All versions
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'crispy_forms'
This error occurs when the `django-crispy-forms` package is not correctly installed in the Python environment being used by your Django project, or the virtual environment is not activated. [1, 3, 4, 9, 18]
fixEnsure you have installed the package using `pip install django-crispy-forms` within your project's virtual environment. If using an IDE like PyCharm, verify the correct Python interpreter is selected for your project. [1, 4, 9]
TemplateSyntaxError: 'crispy_forms_tags' is not a valid tag library
This error indicates that Django cannot find the `crispy_forms_tags` library. The most common reason is that 'crispy_forms' has not been added to your `INSTALLED_APPS` in your Django project's `settings.py` file, or there's a typo in the `{% load crispy_forms_tags %}` statement. [2, 22]
fixAdd `'crispy_forms'` to your `INSTALLED_APPS` list in `settings.py` and ensure `{% load crispy_forms_tags %}` is correctly placed at the top of your Django template. [2, 22] TemplateDoesNotExist: bootstrap4/uni_form.html
This error, or similar `TemplateDoesNotExist` errors for other template packs (e.g., `bootstrap5/uni_form.html`), often occurs in `django-crispy-forms` versions 2.0 and later because template packs are no longer bundled with the main library and must be installed separately. [8, 15, 16, 20]
fixInstall the specific template pack corresponding to your chosen CSS framework (e.g., `pip install crispy-bootstrap4` or `pip install crispy-bootstrap5`) and add it to your `INSTALLED_APPS` (e.g., `'crispy_bootstrap4'` or `'crispy_bootstrap5'`) in `settings.py`. Also, set `CRISPY_ALLOWED_TEMPLATE_PACKS` and `CRISPY_TEMPLATE_PACK` in `settings.py` to match your installed pack. [8, 16, 20]
Invalid filter: 'crispy'
This `TemplateSyntaxError` happens when the `crispy` filter is used in a Django template, but the `crispy_forms_tags` template library has not been loaded, or there's a typo in the filter usage. [22]
fixEnsure that `{% load crispy_forms_tags %}` is present at the top of your Django template before using `{{ form|crispy }}`. [22] Upgrade
Version history
2.7latest on PyPI · released Jul 29, 2026
Audit
Dependencies
DjangorequiredCore dependency for any Django application.
crispy-bootstrap2optionalOptional, provides Bootstrap 2 template pack. Required since 2.0 if using Bootstrap 2.
crispy-bootstrap3optionalOptional, provides Bootstrap 3 template pack. Required since 2.0 if using Bootstrap 3.
crispy-bootstrap4optionalOptional, provides Bootstrap 4 template pack. Required since 2.0 if using Bootstrap 4.
crispy-bootstrap5optionalOptional, provides Bootstrap 5 template pack. Required since 2.0 if using Bootstrap 5.