Forms are basically used for taking input from the user. For adding, updating, retrieving that information to databases using GET or POST request. There is two forms classes in Django which is used to create HTML forms. Form & ModelForm. The difference between the Form & ModelForm class is that ModelForm class needs a model to create a form, but the Form class does not require a Model. We will discuss both here. Each field of the Form class map to the HTML form  <input>  element and each field has custom validation logic. Django does three distinct parts of the work involved in forms:

  • Prepares and Restructures data to make it ready for rendering
  • Creates HTML forms for the data.
  • Receives and Processes submitted data from the user.

forms.Form

Creating forms in Django is similar to creating a model. We just need to inherit from Django Form class and the attributes of the class will be the form fields. 

Let’s see an example. We will make a ‘forms.py’ file and add this code snippet to it.

from django import forms  

class UserForm(forms.Form):
    first_name = forms.CharField(label="Enter first  name",max_length=100)  

    last_name  = forms.CharField(label="Enter last name", max_length = 100)  
views.py
from first_app.forms import UserForm  
      
def user_form(request):  
    form = UserForm()  
    return render(request,"user-form.html",{'form':form})  
user-form.html
<!DOCTYPE html>  
<html lang="en">  
<head>  
    <meta charset="UTF-8">  
    <title>Index</title>  
</head>  
<body>  
  <form method="POST">  
       {% csrf_token %}  
       {{ form.as_p }}  
        <button type="submit" class="save btn btn-default">Save</button>  
   </form>  
</body>  
</html>  

Here, {% csrf_token %} token adds protection against Cross Site Request Forgeries. This is used only in POST requests. We don’t need it with GET requests.

Now, let’s add URL in urls.py

urlpatterns = [
         path('user-form', user_form, name='user-form'),
]

We created a UserForm that contains two fields of CharField type. CharField is used to create an HTML text input component in the form. The label sets the HTML label of the component and ‘max_length’  sets the length of an input value. Here, we didn’t put HTML <input> tags. But {{ form }} variable will create necessary HTML tags for us. When rendered, it will produce the following HTML code in the browser.

Run Server and access the form at browser by going to this url localhost:8000/user-form, and it will produce the following output.

We cannot generate the ‘submit’ button or <form> tag using Django, We’ll have to provide those in the template.

How to Render Django Forms

There are three in-built output options for django forms.

  • {{ form.as_table }} will give output as table cells wrapped in <tr> tags
  • {{ form.as_p }} will give output wrapped in <p> tags
  • {{ form.as_ul }} will give output wrapped in <li> tags

Some Form fields and their details are given in the below table.

Name Class HTML Input
BooleanField  BooleanField(**kwargs) CheckboxInput
CharField CharField(**kwargs) TextInput
ChoiceField ChoiceField(**kwargs) Select
DateField DateField(**kwargs) DateInput
DateTimeField DateTimeField(**kwargs) DateTimeInput
DecimalField DecimalField(**kwargs) NumberInput
EmailField EmailField(**kwargs) EmailInput
FileField FileField(**kwargs) ClearableFileInput
ImageField ImageField(**kwargs) ClearableFileInput

Let’s see a complete example. We will create an HTML form with the help of the Django Form class and saving them in a database.

Instantiating Form in Django

Now, we need to instantiate the form in views.py file. See, the below code.

from first_app.forms import UserForm
  
class AddPersonViewTwo(FormView):
    form_class = UserForm
    template_name = 'user-form.html'
    success_url = '/all-persons'

    def form_valid(self, form):
        # This method is called when valid form data has been POSTed.
        # created a person object
        obj = Person()
        # clean data from 'form' and assign them into objects attributes
        obj.first_name = form.cleaned_data['first_name']
        obj.last_name = form.cleaned_data['last_name']
        #finally save the object in db
        obj.save()
        return HttpResponse("Object Saved")

Firstly, we created a view and assigned the value of Class attributes (form_class, template_name, success_url). Secondly, we overrode the form_valid method of ‘FormView’ class where we created an object of Person class. As, we know our person class has four attributes; out of them two are required (first_name, last_name). We are also taking these two inputs through our form. Now, we will assign the values taken by ‘Form’ to our Person object attributes. We are done to save data in db. Now we will Add URL for this view and go to the link.

Our Templates will be same as our ‘user-form.html’

Output

Now, if we click the button ‘Add Person’ the data will be saved in the database.

Let’s check our database.

How to use ModelForm in Django

The differences between Form and ModelForm is a form created by forms. ModelForm is a form that is automatically created based on a specific model. forms.Form  and  forms.ModelForm are more closely related. The Form class allows us to validate data. It hardly matters if it is a GET, or POST request.

ModelForm is a subclass of the Form class. A ModelForm  works  almost  exactly like a Form class, except that it reads the list of fields from the attribute you provide. Underneath it all, a ModelForm actually just creates a Form with fields that are relevant to the fields of the model you specify, so you don’t have to do it manually.

ModelForm
class AddPersonForm(forms.ModelForm):
    class Meta:
        model = Person
        fields = ('first_name','last_name','email','gender')
View
from .forms import AddPersonForm

class AddPersonView(CreateView):
    form_class = AddPersonForm
    template_name = 'user-form.html'

HTML will be same as before.

Output 

Redirected To Details
In admin panel

In conclusion, use a forms.Form when you have data that you want to validate and use forms.ModelForm when you want to validate data that you will store in your database, using a db.models.Modelclass.

+ posts

Author | Python-Django Developer

+ posts

Full-stack Developer (Python | Django | React | React-Native | Angular | Vue)