Skip to content

Contact sales

By filling out this form and clicking submit, you acknowledge our privacy policy.

Introduction to Django Forms

This guide will explore how to use forms in Django as a data capture tool. The methods and assets needed to generate a form are found in Django's FORM class.

Oct 28, 2020 • 6 Minute Read

Introduction

Web applications run on user interactions. Users enter data that is processed or stored and later displayed via web pages and views. With Django, a crucial component of data collection is forms. The methods and assets needed to generate a form are found in Django's FORM class, which is accessed by the import from django import forms.

This guide will explore how to use forms in Django as a data capture tool. It assumes that you have at least beginner level knowledge in Django and a general understanding of the Django MVC. An introductory guide to Django can be found here.

Forms in Django

Since forms are data entry components, they can be an entry point for malicious attacks, such as SQL injection and cross site request forgery. To prevent this, Django has some security checks, such as a CSRF token and checking form validity before saving. More about form security can be learned from the Django docs.

Sample App

To better understand the use of forms, and specifically model forms in Django, consider a use case where your client wishes to build an inventory management web app. Part of the scope is building a web form for capturing new inventory items as well as a login form. Below is a snippet of the Inventory model that influences how the inventory form is be designed.

      from django.db import models
class Inventory(models.Model):
    item = models.CharField(max_length=20)
    item_code = models.IntegerField()
    item_condition = models.CharField(max_length=50)
    quantity = models.IntegerField()
    def __str__(self):
        return self.item
    

ModelForm

Model forms are components that are derived from an existing model. Simply, they are forms specifically for a model that you specify. Generating a model form is quite easy. Below is a code snippet of one for the Inventory model. As best practice, forms in Django are defined in forms.py.

      from django import forms

from .models import Inventory

class InventoryForm(forms.ModelForm):

    class Meta:
        # the model
        model = Inventory
        # the fields you want visible in the form
        fields = ('item', 'item_code','item_description')
    

For the form to be visible to the user, you have to render it in an HTML file. This means you need both a view and an HTML file.

Form View in views.py

      from .forms import InventoryForm
from django.shortcuts import render
def new_inventory(request):
    if request.method == "POST": # data was sent to server
        form = InventoryForm(request.POST)# instantiate form object with data sent from user   
        if form.is_valid(): # no errors or missing values
            form.save() # save form data to database
    else: # normal get request
        form = InventoryForm() # instantiate empty form
    
    return render(request, 'inventoryapp/add_inventory.html', {'form': form})
    

The code block above renders a model form for the Inventory model onto an HTML page.

Form View in HTML File

Below is a snippet of an HTML file in which the form is rendered. The HTML file is referenced in the new_inventory view as add_inventory.html.

      {% extends 'myapp/base.html' %}

{% block content %}
    <h2>New inventory</h2>
    <form method="POST" class="inventory-form">{% csrf_token %}
        {{ form.as_p }}
        <button type="submit" class="save btn btn-default">Save</button>
    </form>
{% endblock %}
    

Normal Form

This type of form does not serve a model. It is used to get information from the user and process it in one way or another. A common use case is a login form. It is not linked to a model, but you use the username and password to authenticate a user. Below are code snippets for how to set up a simple form

forms.py

      from django import forms

class LoginForm(forms.Form):
    username = forms.CharField(label='Your name', max_length=100)
    password = forms.PasswordInput()
    

views.py

      from django.http import HttpResponseRedirect
from django.shortcuts import render

from .forms import LoginForm

def get_name(request):
    if request.method == 'POST': # data was sent from user
        # instantiate form object with data sent from user
        form = LoginForm(request.POST)
        if form.is_valid(): # no errors
            # authenticate user and log them in
            # redirect to dashboard:
            return HttpResponseRedirect('/dashboard/')
    else: # get request
        form = LoginForm()

    return render(request, 'login.html', {'form': form})
    

HTML File

      <form action="/login/" method="post">
    {% csrf_token %}
    {{ form }}
    <input type="submit" value="Submit">
</form>
    

Third-party Packages

The basic forms rendered are not usually as appealing as one would wish. They need more work on styling. For this, third-party packages have been developed to style forms and give them a face lift. The most common are:

  1. Django widget tweaks

  2. Django crispy forms

Conclusion

Mastery of form manipulation and associated methods gives you the power to design better and more efficient data collection techniques within a Django web app.

To further build on this guide and your knowledge of forms, follow this official guide to learn more about FormMixins, classes that provide methods and facilities for creating and displaying forms. They are most commonly used with Class-based Views (CBV).

Kimaru Thagana

Kimaru T.

Kimaru is a firm believer of education as a tool of self sufficiency. As software development consultant, living in Kenya, he mainly works to bring small and medium sized business to the internet with custom solutions ranging from data processing to business digitization. Away from the field of coding and computer science, he participates as a mentor for young university students. In his free time, he prefers peace and quiet, away from screens but close to nature.

More about this author