Easy Tutorial
❮ Django Model Django Nginx Uwsgi ❯

Django Form Component

The Django Form component is used to initialize pages, generate HTML tags, and additionally, it can validate user-submitted data (displaying error messages).

Error Message Display Order:

To use the Form component, you need to import forms first:

from django import forms

Next, we create a My_forms.py file under the app01 directory:

app01/My_forms.py

from django import forms
from django.core.exceptions import ValidationError
from app01 import models

class EmpForm(forms.Form):
    name = forms.CharField(min_length=4, label="Name", error_messages={"min_length": "Too short", "required": "This field cannot be empty!"})
    age = forms.IntegerField(label="Age")
    salary = forms.DecimalField(label="Salary")

Field Attributes:

app01/views.py

from django.shortcuts import render, HttpResponse
from app01.My_Forms import EmpForm
from app01 import models
from django.core.exceptions import ValidationError
# Create your views here.

def add_emp(request):
    if request.method == "GET":
        form = EmpForm()
        return render(request, "add_emp.html", {"form": form})
    else:
        form = EmpForm(request.POST)
        if form.is_valid():  # Perform data validation
            # Validation successful
            data = form.cleaned_data  # Validated values will be stored in cleaned_data.
            data.pop('r_salary')
            print(data)

            models.Emp.objects.create(**data)
            return HttpResponse('ok')
            # return render(request, "add_emp.html", {"form": form})
        else:
            print(form.errors)  # Print error messages
            clean_errors = form.errors.get("__all__")
            print(222, clean_errors)
        return render(request, "add_emp.html", {"form": form, "clean_errors": clean_errors})

Add the following rule to the app01/urls.py file:

path('add_emp/', views.add_emp)

HTML Template:

app01/add_emp.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>

<h3>Add Employee</h3>

{#1. Manually write the HTML page#}
<form action="" method="post">
<p>Name: <input type="text" name="name"></p>
<p>Age: <input type="text" name="age"></p>
<p>Salary: <input type="text" name="salary"></p>
<input type="submit">
</form>

{#2. Implementing using the as_p method of the form object#}
{#&lt;form action="" method="post" novalidate>#}
{#    {% csrf_token %}#}
{#    {{ form.as_p }}#}
{#    <input type="submit">#}
{#</form>#}

{#3. Manually fetching fields of the form object#}
{#&lt;form action="" method="post" novalidate>#}
{#    {% csrf_token %}#}
{#    <div>#}
{#        <label for="id_{{ form.name.name }}">Name</label>#}
{#        {{ form.name }} <span>{{ form.name.errors.0 }}</span>#}
{#    </div>#}
{#    <div>#}
{#        <label for="id_{{ form.age.name }}">Age</label>#}
{#        {{ form.age }} <span>{{ form.age.errors.0 }}</span>#}
{#    </div>#}
{#    <div>#}
{#        <label for="id_salary">Salary</label>#}
{#        {{ form.salary }} <span>{{ form.salary.errors.0 }}</span>#}
{#    </div>#}
{#    <input type="submit">#}
{#</form>#}

{#4. Displaying all fields using a for loop#}
{#&lt;form action="" method="post" novalidate>#}
{#    {% csrf_token %}#}
{#    {% for field in form %}#}
{#        <div>#}
{#            <label for="id_{{ field.name }}">{{ field.label }}</label>#}
{#            {{ field }} <span>{{ field.errors.0 }}</span>#}
{#        </div>#}
{#    {% endfor %}#}
{#    <input type="submit">#}
{#</form>#}

</body>
</html>

Local and Global Hooks

Defining the Form class:

app01/My_forms.py

from django import forms
from django.core.exceptions import ValidationError
from app01 import models
class EmpForm(forms.Form):
    name = forms.CharField(min_length=5, label="Name", error_messages={"required": "This field cannot be empty!",
                                                                        "min_length": "The username is too short."})
    age = forms.IntegerField(label="Age")
    salary = forms.DecimalField(max_digits=5, decimal_places=2, label="Salary")
    r_salary = forms.DecimalField(max_digits=5, decimal_places=2, label="Please re-enter the salary")

    def clean_name(self):  # Local hook
        val = self.cleaned_data.get("name")

        if val.isdigit():
            raise ValidationError("The username cannot be purely numeric")
if models.Emp.objects.filter(name=val):
    raise ValidationError("Username already exists!")
else:
    return val

def clean(self):  # Global hook to confirm if the salary inputs match.
    val = self.cleaned_data.get("salary")
    r_val = self.cleaned_data.get("r_salary")

    if val == r_val:
        return self.cleaned_data
    else:
        raise ValidationError("Please confirm if the salaries match.")
# app01/views.py

def add_emp(request):
    if request.method == "GET":
        form = EmpForm()  # Initialize form object
        return render(request, "add_emp.html", {"form": form})
    else:
        form = EmpForm(request.POST)  # Pass data to form object
        if form.is_valid():  # Perform validation
            data = form.cleaned_data
            data.pop("r_salary")
            models.Emp.objects.create(**data)
            return redirect("/index/")
        else:  # Validation failed
            clear_errors = form.errors.get("__all__")  # Get global hook error messages
            return render(request, "add_emp.html", {"form": form, "clear_errors": clear_errors})
<!-- app01/add_emp.html -->

&lt;form action="" method="post" novalidate>
    {% csrf_token %}
    <div>
        <label for="id_{{ form.name.name }}">Name</label>
        {{ form.name }} <span>{{ form.name.errors.0 }}</span>
    </div>
    <div>
        <label for="id_{{ form.age.name }}">Age</label>
        {{ form.age }} <span>{{ form.age.errors.0 }}</span>
    </div>
    <div>
        <label for="id_salary">Salary</label>
        {{ form.salary }} <span>{{ form.salary.errors.0 }}{{ clear_errors.0 }}</span>
    </div>
    <div>
        <label for="id_r_salary">Please re-enter salary</label>
        {{ form.r_salary }} <span>{{ form.r_salary.errors.0 }}{{ clear_errors.0 }}</span>
    </div>
    <input type="submit">
</form>
❮ Django Model Django Nginx Uwsgi ❯