Render a Django Bootstrap Form

ยท8 min read

Render a Django Bootstrap Form

Using Django and Bootstrap to render forms is a quick and easy way to create a legible and well-formatted form with all of the necessary functionality.

We will use django-crispy-forms, a Python package with built-in support for the Bootstrap CSS framework, along with the BootstrapCDN to quickly add Bootstrap to our project.

We will start with a brief Django crispy forms tutorial before moving on to the CDNs, filter, and tags required when creating a Django Bootstrap form. 

If you are new to Django forms, learn how to build a contact form to get started before moving on to styling the form.

 

 

Django crispy forms

The Django crispy forms package lets you control how Django forms render in your HTML template through the use of the crispy filter and the crispy tag. It only takes a few minutes to install and add to your existing Django form. This package really makes styling Django forms with Bootstrap CSS simple. 

 

pip install django-crispy-forms

macOS Terminal

(env)User-Macbook:mysite user$ pip install django-crispy-forms

Windows Command Prompt

(env) C:\Users\Owner\desktop\code\env\mysite>pip install django-crispy-forms

Start by installing django-crispy-forms in your activated virtual environment. This package allows you to control the rendering behavior of your Django forms without adding any custom form CSS.

 

Add crispy-forms to settings.py

env > mysite > main > settings.py

INSTALLED_APPS = [
    'main.apps.MainConfig',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'crispy_forms',
]

When the installation is completed, add Django crispy_forms to your INSTALLED_APPS. Be sure to only add the installed apps as crispy_froms.

The installed app is not django-crispy-forms or django_crispy_forms. Django crispy forms will not work if your spell the app name incorrectly. 

 

Add the crispy template pack

INSTALLED_APPS = [
    'main.apps.MainConfig',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'crispy_forms',
]

CRISPY_TEMPLATE_PACK = 'bootstrap4'

Next, add the crispy_template_pack = 'bootstrap 4' below the INSTALLED_APPS. The crispy_template_pack is the built-in support for different CSS frameworks, including Bootstrap.

Django crispy forms comes with the 'bootstrap', 'bootstrap3', 'bootstrap4', and 'unif-form' template packs already created. But they do have the option to create your own template pack form the CSS framework of your choice. 

For this tutorial, let's use the django-crispy-forms bootstrap 4 template pack. 

If you forget to add the crispy template pack, the Django form will not be styled with Bootstrap CSS.

 


 

Django render form

Rendering a Django form is relatively simple. All you need to do is pass your form of choice in as context in a view function, then call it in the template. 

env > mysite > main > templates > main > home.html

<!DOCTYPE html>
<html>
  <head>
    </head>
    <body>

    <!--Contact form-->
    <div>
      <h1>Contact</h1>
      <h4>Contact us directly if you have any questions</h4>
      <p>
        Please write your name, email address and a message below if you have any questions.
        One of our staff members will be happy to contact you directly and answer your questions as soon as possible. 
      </p>
      <form method="post">
          {% csrf_token %}
              {{form}}
              <button type="submit">Submit</button>
          </form>
      </div>

    </body>
</html>

On the template file of your choice, and add a form HTML element below the text.  Add method="POST" to the opening tags of the form element. This is so the form is posted upon submission.

Next, nest the {% csrf_token %} within the opening and closing tags of the form element to prevent form submission forgery.  This is a built-in Django tag and an important line of code used to securely send information. The form will not post if you forget the csrf token. 

Now you can call your {{form}} variable. Then add a submit button right before the closing tag of the form element. 

If you are unsure how to connect your forms.py to the Django template, review the article Build a Django Contact Form.

 


 

How to style Django forms with Bootstrap

Rendering a Django form with a Bootstrap either requires you to pip install bootstrap4 or add the Bootstrap CDN and JavaScript to the file. 

 

Add BootstrapCDN to Django template

env > mysite > main > templates > main > home.html

<!DOCTYPE html>
<html>
  <head>
      <!-- Required meta tags -->
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <!--Bootstrap CSS-->
      <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
    </head>
    <body>

        <!--Contact form-->
        ...
    

    <!-- Optional Javascript -->
      <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
      <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
      <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
    </body>
</html>

Start by adding the Bootstrap CSS and JavaScript to your HTML template. This way, you can use the Bootstrap CSS without having to unnecessarily add your own Django form CSS.

 

Load in the crispy forms tags

env > mysite > main > templates > main > home.html

<!DOCTYPE html>
<html>
  <head>
      <!-- Required meta tags -->
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <!--Bootstrap CSS-->
      <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
    </head>
    <body>

    {% load crispy_forms_tags %}  

    <!--Contact form-->
    ...

    <!-- Optional Javascript -->
      <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
      <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
      <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
    </body>
</html>

Next, load crispy_forms_tags at the top of the file. 

 

Using the Django crispy form filter

env > mysite > main > templates > main > home.html

<!DOCTYPE html>
<html>
  <head>
      <!-- Required meta tags -->
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <!--Bootstrap CSS-->
      <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
    </head>
    <body>

    {% load crispy_forms_tags %}  

    <!--Contact form-->
    <div>
      <h1>Contact</h1>
      <h4>Contact us directly if you have any questions</h4>
      <p>
        Please write your name, email address and a message below if you have any questions.
        One of our staff members will be happy to contact you directly and answer your questions as soon as possible. 
      </p>
      <form method="post">
          {% csrf_token %}
              {{form|crispy}}
              <button type="submit">Submit</button>
          </form>
      </div>

    <!-- Optional Javascript -->
      <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
      <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
      <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
    </body>
</html>

Finally, you can add the |crispy filter to the Django form. This filter will automatically format each field within the form with django-crispy-forms Bootstrap 4 CSS. 

If you run the server again, the Django form fields should have the appearance of a form with Bootstrap CSS.

 

Using the Django as_crispy_field form filter

env > mysite > main > templates > main > home.html

<!DOCTYPE html>
<html>
  <head>
      <!-- Required meta tags -->
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <!--Bootstrap CSS-->
      <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
    </head>
    <body>

    {% load crispy_forms_tags %}  

    <!--Contact form-->
    <div>
      <h1>Contact</h1>
      <h4>Contact us directly if you have any questions</h4>
      <p>
        Please write your name, email address and a message below if you have any questions.
        One of our staff members will be happy to contact you directly and answer your questions as soon as possible. 
      </p>
      <form method="post">
          {% csrf_token %}
              {{form.first_name|as_crispy_field}}
              {{form.last_name|as_crispy_field}}
              {{form.email_address|as_crispy_field}}
              {{form.comment|as_crispy_field}}
              <button type="submit">Submit</button>
          </form>
      </div>

    <!-- Optional Javascript -->
      <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
      <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
      <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
    </body>
</html>

If you wish to call each form field individually, use the format {{form.name_of_field|as_crispy_field}}. That way, you can change the order in which the form fields display. 

 

Styling Django forms with Bootstrap columns and rows

env > mysite > main > templates > main > home.html

<!DOCTYPE html>
<html>
  <head>
      <!-- Required meta tags -->
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <!--Bootstrap CSS-->
      <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
    </head>
    <body>

    {% load crispy_forms_tags %}  

    <!--Contact form-->
    <div class="container p-5">
      <h1>Contact</h1>
      <h4>Contact us directly if you have any questions</h4>
      <p>
        Please write your name, email address and a message below if you have any questions.
        One of our staff members will be happy to contact you directly and answer your questions as soon as possible. 
      </p>
      <form method="post">
          {% csrf_token %}
          <div class="row">
            <div class="col-lg-6 col-md-12">
              {{form.first_name|as_crispy_field}}
            </div>
            <div class="col-lg-6 col-md-12">
              {{form.last_name|as_crispy_field}}
            </div>
          </div>
          <div class="row">
              {{form.email_address|as_crispy_field}}
          </div>
          <div class="row">
              {{form.comment|as_crispy_field}}
          </div>
              <button type="submit">Submit</button>
          </form>
      </div>

    <!-- Optional Javascript -->
      <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
      <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
      <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
    </body>
</html>

Besides having the ability to change the order of the Django form fields, using the as_crispy_field filter also allows you to style the Django form with Bootstrap rows and columns. Above is an example of how Django crispy forms in addition to Bootstrap can change the Django form CSS in a way that displays the fields more effectively to the user.

Save the changes to the file then run the server. The forms should now be formatted in rows while keeping the same Django form functionality.

 


 

Django login forms Bootstrap 

If you are interested in using Django crispy-forms to create login forms, check out the Guide to User Registration, Login, and Logout then head over to 14 Custom User Login Forms to get some CSS ideas for the template.

 


 

Django crispy forms is not working 

If you are running into errors when using Django crispy forms package:

  1. Check that the installed package is named correctly.
  2. Make sure to add the crispy_template_pack to the settings.
  3. Be sure to load crispy_forms_tags at the top of the HTML template.
  4. The form filter used needs to either be |crispy or |as_crispy_field.

Check out the article Stuck on the Django Yellow Page? for more details regarding these errors.