Django Crispy Forms
Tags: tutorial, django, djangocrispyform, python
Published: 2023-02-16 09:09:24

Django Crispy Forms is a third-party package for Django that helps you create elegant, DRY forms. In this tutorial, we will go over the basics of using Django Crispy Forms to create and customize forms in your Django application.

Installing Django Crispy Forms

To get started with Django Crispy Forms, you first need to install it. You can install it using pip by running the following command:

```bash
pip install django-crispy-forms
```
Once installed, add 'crispy_forms' to the INSTALLED_APPS setting in your Django project's `settings.py` file:

```python
INSTALLED_APPS = [
    # ...
    'crispy_forms',
    # ...
]
```
Finally, add the following to your `settings.py` file to tell Django to use crispy forms as the default form rendering engine:

```python
CRISPY_TEMPLATE_PACK = 'bootstrap4'
```

In this tutorial, we will be using Bootstrap 4 as our default template pack, but you can use any other template pack of your choice.

Creating a form

Now that Django Crispy Forms is installed and set up, let's create a form. In this example, we will create a simple contact form with three fields: name, email, and message.

Create a new file called `forms.py` in your Django app's directory and add the following code:

```python
from django import forms
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Submit

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(ContactForm, self).__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.helper.form_id = 'id-contact-form'
        self.helper.form_method = 'post'
        self.helper.add_input(Submit('submit', 'Send message'))
```
In the above code, we define a ContactForm class that inherits from Django's forms.Form class. We define three fields: name, email, and message. We also use the crispy_forms package to create a FormHelper object, which we use to add a Submit button to the form.

Using the form in a view

Now that we have defined our form, let's use it in a view. Create a new file called `views.py` in your app's directory and add the following code:

```python
from django.shortcuts import render
from .forms import ContactForm

def contact(request):
    if request.method == 'POST':
        form = ContactForm(request.POST)
        if form.is_valid():
            # Do something with the form data
            pass
    else:
        form = ContactForm()

    return render(request, 'contact.html', {'form': form})
```
In the above code, we define a contact view that renders a contact.html template and passes a ContactForm instance to the template context. If the form is submitted via POST, we validate the form and do something with the form data if it is valid.

Rendering the form in a template

Now that we have defined the form and the view, let's render the form in a template. Create a new file called contact.html in your app's templates directory and add the following code:
```html
{% extends 'base.html' %}

{% block content %}
  <h1>Contact us</h1>
  <form method="post" id="{{ form.helper.form_id }}">
    {% csrf_token %}
    {{ form.as_p }}
  </form>
{% endblock %}
```
In the above code, we extend a base template and define a content block. We then render a h1 tag and the contact form, which is passed to the template context as form. The form.as_p method renders the form as a series of paragraphs, and we also include a CSRF token for security purposes.

Customizing the form layout

One of the advantages of using Django Crispy Forms is that it allows you to easily customize the layout of your forms. In our previous example, we used the default layout, which is a series of paragraphs. Let's customize the form layout by using Bootstrap 4's grid system.

To customize the layout of the form, we need to define a Layout object and add it to the FormHelper object. Modify the ContactForm class as follows:

```python
from crispy_forms.layout import Layout, Field

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(ContactForm, self).__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.helper.form_id = 'id-contact-form'
        self.helper.form_method = 'post'
        self.helper.add_input(Submit('submit', 'Send message'))

        self.helper.layout = Layout(
            Field('name', css_class='form-control'),
            Field('email', css_class='form-control'),
            Field('message', css_class='form-control'),
        )
```
In the above code, we define a Layout object that contains three Field objects, one for each field in the form. We also add the css_class attribute to each Field object to apply Bootstrap 4's form-control class to each input element.

Finally, let's modify the contact.html template to use Bootstrap 4's form layout. Replace the contents of the template with the following:

```html
{% extends 'base.html' %}

{% block content %}
  <div class="container">
    <h1>Contact us</h1>
    <form method="post" id="{{ form.helper.form_id }}">
      {% crispy form %}
    </form>
  </div>
{% endblock %}
```
In the above code, we wrap the form in a Bootstrap 4 container class and use the crispy template tag to render the form using the FormHelper object we defined earlier.

That's it! With Django Crispy Forms, you can create and customize forms quickly and easily, with minimal boilerplate code.