How to Display Form Error in Django

Posted on

This article shows how to display an error within a form after submitting a POST request in Django. If there is an error, Django will display the detail of the error in an error message. The following is the output of a submitted form using POST request but there is a an error on that form :

The above is a form with the following directory tree project of Django framework :

(base) user@hostname:~/python/project$ tree -L 2
.
├── app
│   ├── admin.py
│   ├── apps.py
│   ├── forms.py
│   ├── __init__.py
│   ├── migrations
│   ├── models.py
│   ├── __pycache__
│   ├── tests.py
│   ├── urls.py
│   └── views.py
├── db.sqlite3
├── manage.py
├── project
│   ├── __init__.py
│   ├── __pycache__
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
└── static
    ├── css
    ├── img
    └── js

The following is the content of several important files to display how to show error message. The first file is the models.py file. Below is the content of that file :

from django.db import models

# Create your models here.
class MyModel(models.Model):
    name = models.CharField(max_length=100)

The next one is the content of a file with the name of ‘forms.py’ :

from django import forms
from app.models import MyModel

class MyForm(forms.ModelForm):
    name = forms.CharField()

    class Meta:
        model = MyModel
        fields = ('name',)

Next, it is the ‘views.py’ file containing the method or function for processing the submit POST request from the page. The following is the content of the files :

def add(request):
    if request.method == "POST" or None:
        form = MyForm(request.POST or None)
        if  form.is_valid():
            form.save(commit=False)
            print(form)
            print("Valid Form")
            form.save()
            return render(request,'app/list.html',{'form':form})
        else:
            print(form)
            print("Invalid Form")
            print(form.errors)
            return render(request, 'app/add.html',{'form':form})
    else:
        return render(request, 'app/add.html')

The next one is the content of the template file for rendering the output. Below is a file with the name of ‘add.html’. The file itself exist inside the templates directory. The following is the content of the ‘add.html’ file :

{% extends 'app/base.html' %}
{% block content %}
<form method="POST" action="{% url 'app-add' %}">
{% csrf_token %}
    <div class="form-group">
        <label for="exampleInputName">Name</label>
        <input type="text" class="form-control" name="name" aria-describedby="name" placeholder="Name">        
    </div>

    {% if form.errors %}
       {% for field in form %}
           {% for error in field.errors %} 
              <div class="alert alert-danger">
                   <strong>{{ error|escape }}</strong>
              </div>
           {% endfor %}
       {% endfor %}
    {% endif %}
    <button type="submit" class="btn btn-primary">Submit</button>
</form>
{% endblock %}

The most important thing in the above snippet code for displaying error message is in the following tag :

{% if form.errors %}
       {% for field in form %}
           {% for error in field.errors %} 
              <div class="alert alert-danger">
                   <strong>{{ error|escape }}</strong>
              </div>
           {% endfor %}
       {% endfor %}
    {% endif %}

Don’t forget to check the variable name before defining in the above error form message. It is using a variable with the name of ‘form’. It is consistent with the method definition in the view for passing the variable name to the html file page. It shows in the following line of code :

   return render(request, 'app/add.html',{'form':form})

So, basically, since the form is not valid, the interpreter will execute the else block part. So, that line part above is in the execution process. Along with the execution process, a variable with the name of ‘form’ will pass as an additional data to the template page file with the name of ‘add.html’ in folder ‘app’. The ‘form’ variable itself is in the previous definition as in the following line of code :

        form = MyForm(request.POST or None)

Leave a Reply