Using django_crispy_forms to style django forms

Django, by default, renders its form without styling. This was done on purpose to give developers complete freedom to style their forms however they see fit. 

We discussed how to create a Django form here: creating forms with django. In this session, we will discuss how we can use django_crispy_form to render django forms. We will implement how we can add  django_crispy_form to our previous form

Why Django_crispy_form ?

 Django_crispy_form  allow you to style Django form HTML template without having to write HTML in the template. Django_crispy_form renders Django form in an elegant and DRY(Don't repeat yourself) way. The django_crispy_form  works perfectly with bootstrap. The setting can be done in the settings.py file.

To use django_crispy_form , the first step is to install using the comand below:

pip install django-crispy-form

Once installed add crispy_forms to your INSTALLED_APPS in settings.py

We will be using bootstrap5 for our django form. We will have to install Bootstrap5 template pack for django-crispy-form.

pip install crispy-bootstrap5

We als need to update crispy_bootstrap5 in our INSTALLED_APPS

Finally, in our setting.py , we will have to set bootstrap5 as and allowed template pack and as the default template pack for your project:

INSTALLED_APPS = (
    ...
    "crispy_forms",
    "crispy_bootstrap5",
    ...
)
CRISPY_ALLOWED_TEMPLATE_PACKS = "bootstrap5"
CRISPY_TEMPLATE_PACK = "bootstrap5"

Recall from  creating forms with django, this is how our models.py and forms.py look like.

models.py

from django.db import model

class Contact(models.Model):
        name = model.CharField(max_length = 200)
        email = models.EmailField()
        phone = models.CharField(max_length = 15)
        message = models.TextField()

        def __str__(self):
                return self.name

forms.py

from django.forms import ModelForm
from .models import Contact

class ContactForm(ModelForm):
       class Meta:
                model = Contact
                fields = ["name", "email", "phone", "message"] 

let's use the crispy_form to design our form in the template like so:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- Latest compiled and minified CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-0evHe/X+R7YkIZDRvuzKMRqM+OrBnVFBL6DOitfPri4tjfHxaWutUpFmBp4vmVor" crossorigin="anonymous">

<!-- Latest compiled and minified JavaScript -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/js/bootstrap.bundle.min.js" integrity="sha384-pprn3073KE6tl6bjs2QrFaJGz5/SUsLqktiwsUTF55Jfv3qYSDhgCecCxMW52nD2" crossorigin="anonymous"></script>

{% load crispy_forms_tags %}

</head>

<body>

<div class = "mt-5 d-flex justify-content-center">
<div class="card">
<div class="card-body">
<h1 class ="text-center">Django Contact form </h1>
<form method = "POST" id='form' class="form-control-lg">
{% csrf_token %}
{{ form|crispy}}
<button type = "submit" class = " btn btn-primary ">Send</button>
</form>
</div>
</div>
</div>
</body>
</html>

In the template, the crispy form is called using {% load crispy_forms_tags %}.

The form will be rendered like so: {{ form|crispy }}.

Our beautiful form will look like so:

There are so many things you can do with django_crispy_forms without breaking the standard way of doing things in Django. To learn more about django_crispy_form, visit their github page: django_crispy_form.