Lesson 42 of 60 – Django Model Forms
70%

Django Model Forms

Django Model Forms provide a convenient way to create forms directly from Django models. They connect a form with a database model and can simplify creating and updating database records.

Instead of defining every form field manually, a ModelForm can generate form fields based on the fields defined in a model.

Note: ModelForm is especially useful for admission forms, student management systems, registration forms, product forms, and CRUD applications.

1. What is ModelForm?

A ModelForm is a Django form that is connected to a model.

For example, if you have a Student model containing:

name
email
mobile
course

A ModelForm can automatically create corresponding form fields for these model fields.

2. Why Use ModelForm?

ModelForm reduces the amount of code required to create forms connected to database models.

  • Automatically creates form fields from model fields.
  • Provides validation based on model fields.
  • Can save valid data directly to the database.
  • Can be used for creating records.
  • Can be used for updating records.
  • Reduces repetitive form code.

3. Importing ModelForm

ModelForm is available through Django's forms module.

from django import forms

You can then create a class that inherits from forms.ModelForm.

4. Creating a Student Model

Suppose we have the following Student model:

from django.db import models

class Student(models.Model):

    name = models.CharField(
        max_length=100
    )

    email = models.EmailField()

    mobile = models.CharField(
        max_length=15
    )

    age = models.IntegerField()

    def __str__(self):
        return self.name

A ModelForm can be created from this model.

5. Creating a Basic ModelForm

Create a form class using forms.ModelForm.

from django import forms
from .models import Student

class StudentForm(forms.ModelForm):

    class Meta:

        model = Student

        fields = [
            "name",
            "email",
            "mobile",
            "age"
        ]

Django will generate form fields based on the selected model fields.

6. Understanding the Meta Class

The inner Meta class provides configuration information for the ModelForm.

class Meta:

    model = Student

    fields = [
        "name",
        "email"
    ]

It tells Django which model the form is connected to and which model fields should be included.

7. Using fields

The fields option specifies which model fields should appear in the form.

class Meta:

    model = Student

    fields = [
        "name",
        "email"
    ]

Only Name and Email will be included in the generated form.

8. Using fields = "__all__"

You can include all model fields using "__all__".

class Meta:

    model = Student

    fields = "__all__"

This tells Django to include all editable model fields in the form.

Tip: Explicitly listing fields is often clearer because it makes the form's intended fields obvious.

9. Excluding Fields

The exclude option can be used to leave specific model fields out of the form.

class Meta:

    model = Student

    exclude = [
        "age"
    ]

The Age field will not be included in the generated form.

10. Rendering ModelForm in a Template

Pass the ModelForm to a template from the view.

return render(
    request,
    "student_form.html",
    {"form": form}
)

Then render the form:

<form method="post">

    {% csrf_token %}

    {{ form.as_p }}

    <button type="submit">
        Save
    </button>

</form>

11. Creating Records with ModelForm

A ModelForm can save submitted data directly into the database.

if form.is_valid():

    form.save()

The save() method creates a database record when the form is used without an existing instance.

12. Complete Create View

from django.shortcuts import render
from .forms import StudentForm

def student_create(request):

    if request.method == "POST":

        form = StudentForm(
            request.POST
        )

        if form.is_valid():

            form.save()

    else:

        form = StudentForm()

    return render(
        request,
        "student_form.html",
        {"form": form}
    )

The form is displayed for GET requests and processed for POST requests.

13. Using redirect After Save

After successfully saving a record, redirecting to another page can prevent duplicate form submissions.

from django.shortcuts import (
    render,
    redirect
)

if form.is_valid():

    form.save()

    return redirect(
        "student_list"
    )

This is commonly used after successful POST requests.

14. Updating a Record with ModelForm

A ModelForm can also update an existing model instance.

student = Student.objects.get(
    id=1
)

form = StudentForm(
    instance=student
)

The existing student's values are displayed in the form.

15. Saving an Updated Record

When processing submitted data for an existing record, pass the same instance to the ModelForm.

form = StudentForm(
    request.POST,
    instance=student
)

if form.is_valid():

    form.save()

Django updates the existing record instead of creating a new one.

16. Create vs Update

Operation ModelForm
Create StudentForm(request.POST)
Update StudentForm(request.POST, instance=student)

The instance argument is the important difference when updating an existing record.

17. ModelForm Validation

ModelForms use Django's form validation system and model field information to validate submitted data.

if form.is_valid():

    form.save()

For example, an EmailField can validate email input and required fields can reject empty values.

18. cleaned_data in ModelForm

After successful validation, cleaned values are available through cleaned_data.

if form.is_valid():

    name = form.cleaned_data[
        "name"
    ]

    email = form.cleaned_data[
        "email"
    ]

This is useful when additional processing is required before saving.

19. Custom Form Fields

You can override a generated ModelForm field when you need additional control.

class StudentForm(forms.ModelForm):

    name = forms.CharField(
        max_length=100,
        label="Student Name"
    )

    class Meta:

        model = Student

        fields = [
            "name",
            "email",
            "mobile"
        ]

The custom field replaces the automatically generated field.

20. Custom Widgets

Widgets can be customized in a ModelForm.

class StudentForm(forms.ModelForm):

    class Meta:

        model = Student

        fields = [
            "name",
            "email"
        ]

        widgets = {

            "name": forms.TextInput(
                attrs={
                    "class": "form-control"
                }
            ),

            "email": forms.EmailInput(
                attrs={
                    "class": "form-control"
                }
            )
        }

This allows you to add CSS classes and other HTML attributes.

21. Custom Labels

Labels can be customized using the labels option.

class Meta:

    model = Student

    fields = [
        "name",
        "email"
    ]

    labels = {

        "name": "Student Name",

        "email": "Email Address"
    }

22. Custom Help Text

The help_texts option can provide additional information to users.

class Meta:

    model = Student

    fields = [
        "name",
        "email"
    ]

    help_texts = {

        "name":
        "Enter your full name.",

        "email":
        "Enter a valid email address."
    }

23. Custom Validation in ModelForm

You can define a clean_<fieldname>() method to add custom validation.

class StudentForm(forms.ModelForm):

    class Meta:

        model = Student

        fields = [
            "name",
            "email"
        ]

    def clean_name(self):

        name = self.cleaned_data[
            "name"
        ]

        if len(name) < 3:

            raise forms.ValidationError(
                "Name must contain at least 3 characters."
            )

        return name

24. ModelForm with ForeignKey

A ModelForm can include relationship fields such as ForeignKey.

class Student(models.Model):

    name = models.CharField(
        max_length=100
    )

    course = models.ForeignKey(
        Course,
        on_delete=models.CASCADE
    )

The ModelForm can include the Course field:

class StudentForm(forms.ModelForm):

    class Meta:

        model = Student

        fields = [
            "name",
            "course"
        ]

Django can generate a field for selecting the related Course objects.

25. ModelForm with ManyToManyField

ModelForms can also include ManyToManyField relationships.

class Student(models.Model):

    name = models.CharField(
        max_length=100
    )

    courses = models.ManyToManyField(
        Course
    )

The ModelForm can include:

class StudentForm(forms.ModelForm):

    class Meta:

        model = Student

        fields = [
            "name",
            "courses"
        ]

26. Excluding Sensitive Fields

Not every model field should necessarily be exposed to users through a form.

class StudentForm(forms.ModelForm):

    class Meta:

        model = Student

        fields = [
            "name",
            "email"
        ]

Explicitly selecting fields helps control which model data users can edit.

Important: Avoid exposing fields that users should not be allowed to change.

27. ModelForm with get_object_or_404()

When updating records, get_object_or_404() can be used to safely retrieve the object.

from django.shortcuts import (
    render,
    redirect,
    get_object_or_404
)

def student_edit(request, id):

    student = get_object_or_404(
        Student,
        id=id
    )

    if request.method == "POST":

        form = StudentForm(
            request.POST,
            instance=student
        )

        if form.is_valid():

            form.save()

            return redirect(
                "student_list"
            )

    else:

        form = StudentForm(
            instance=student
        )

    return render(
        request,
        "student_edit.html",
        {"form": form}
    )

28. Complete ModelForm Example

models.py

from django.db import models

class Student(models.Model):

    name = models.CharField(
        max_length=100
    )

    email = models.EmailField()

    mobile = models.CharField(
        max_length=15
    )

    course = models.CharField(
        max_length=100
    )

    def __str__(self):
        return self.name

forms.py

from django import forms
from .models import Student

class StudentForm(forms.ModelForm):

    class Meta:

        model = Student

        fields = [
            "name",
            "email",
            "mobile",
            "course"
        ]

views.py

from django.shortcuts import (
    render,
    redirect
)

from .forms import StudentForm


def student_create(request):

    if request.method == "POST":

        form = StudentForm(
            request.POST
        )

        if form.is_valid():

            form.save()

            return redirect(
                "student_list"
            )

    else:

        form = StudentForm()

    return render(
        request,
        "student_form.html",
        {"form": form}
    )

student_form.html

<form method="post">

    {% csrf_token %}

    {{ form.as_p }}

    <button type="submit">
        Save Student
    </button>

</form>

29. Common ModelForm Mistakes

  • Forgetting to inherit from forms.ModelForm.
  • Forgetting the inner Meta class.
  • Not specifying the model.
  • Forgetting to specify fields or exclude.
  • Forgetting request.POST while processing submitted data.
  • Forgetting {% csrf_token %} in POST forms.
  • Not calling form.is_valid().
  • Forgetting form.save() after successful validation.
  • Not passing instance when updating an existing record.
  • Exposing model fields that users should not edit.

30. ModelForm Summary

ModelForm is one of the most useful Django features for creating database forms.

  • ModelForm connects a form to a Django model.
  • It can automatically generate form fields.
  • Meta.model specifies the model.
  • Meta.fields specifies fields included in the form.
  • fields = "__all__" includes all editable model fields.
  • form.save() can create a database record.
  • The instance argument is used when updating records.
  • Widgets can customize generated HTML controls.
  • Custom validation can be added to ModelForms.
  • ModelForms can work with ForeignKey and ManyToManyField relationships.

📌 Key Points

  • ModelForm connects Django forms with models.
  • Use forms.ModelForm to create a ModelForm.
  • The Meta class defines model and form configuration.
  • fields controls which model fields appear.
  • form.save() can create or update database records.
  • Use instance when updating an existing object.
  • Widgets can customize the appearance of form fields.
  • ModelForms support custom validation.
  • ModelForms can work with relationship fields.
  • Explicitly selecting form fields helps control user input.

🧠 Quick Quiz

Question: Which class is used to create a Django ModelForm?