Django Tutorial menu

Django Forms

Django forms build the HTML inputs, check the submitted data and show errors, all from one Python class.

A Simple Form Class

Create courses/forms.py:

Example

python
from django import forms

class ContactForm(forms.Form):
    name = forms.CharField(max_length=50)
    email = forms.EmailField()
    message = forms.CharField(widget=forms.Textarea)

    def clean_name(self):
        name = self.cleaned_data["name"].strip()
        if len(name) < 3:
            raise forms.ValidationError("Name must be at least 3 letters.")
        return name

A method named clean_<field> adds your own check for that field.

The View

Example

python
from django.shortcuts import render, redirect
from .forms import ContactForm

def contact(request):
    if request.method == "POST":
        form = ContactForm(request.POST)
        if form.is_valid():
            name = form.cleaned_data["name"]
            # send an email or save the message here
            return redirect("thanks")
    else:
        form = ContactForm()
    return render(request, "courses/contact.html", {"form": form})

The flow:

  1. First visit (GET): show an empty form.
  2. The visitor submits (POST): fill the form with request.POST.
  3. is_valid() runs all checks. Clean values go into cleaned_data.
  4. If valid, do the work and redirect. If not, show the form again with errors.

The Template

Example

html
<h1>Contact Us</h1>
<form method="post">
  {% csrf_token %}
  {{ form.as_p }}
  <button type="submit">Send</button>
</form>
  • {% csrf_token %} adds a hidden security token. Django rejects POST forms without it.
  • {{ form.as_p }} prints every field with its label, each in a paragraph.

If a visitor submits the name "Al" and an invalid email, the form comes back showing:

Output
Name must be at least 3 letters.
Enter a valid email address.

Never skip {% csrf_token %}. It stops other websites from sending forms to your site using your visitor's login (a CSRF attack).

Common Form Fields

FieldHTML input
CharFieldText box
CharField(widget=forms.Textarea)Multi-line text
EmailFieldEmail box with email validation
IntegerFieldNumber box
BooleanField(required=False)Checkbox
ChoiceField(choices=...)Drop-down list
DateFieldDate

ModelForm: Forms from Models

When a form saves to a model, a ModelForm builds the fields from the model for you:

Example

python
from django import forms
from .models import Student

class StudentForm(forms.ModelForm):
    class Meta:
        model = Student
        fields = ["name", "email", "course"]

Example

python
from django.shortcuts import render, redirect
from .forms import StudentForm

def register(request):
    form = StudentForm(request.POST or None)
    if request.method == "POST" and form.is_valid():
        student = form.save()
        return redirect("course-detail", course_id=student.course.id)
    return render(request, "courses/register.html", {"form": form})

form.save() creates the Student row in the database. The course field automatically becomes a drop-down of all courses, and unique=True on email is checked for you.

Editing an Existing Row

Pass instance= to fill the form with an existing object:

Example

python
from django.shortcuts import get_object_or_404

def edit_student(request, pk):
    student = get_object_or_404(Student, pk=pk)
    form = StudentForm(request.POST or None, instance=student)
    if request.method == "POST" and form.is_valid():
        form.save()
        return redirect("course-list")
    return render(request, "courses/register.html", {"form": form})

Exercise

Exercise

Where does Django put the checked, cleaned values after form.is_valid() returns True?

Learn Django with a teacher

Join the Full Stack Development course at Workownix, online or in Orangi Town, Karachi, and get a certificate.

See the course Ask on WhatsApp