Paramclasses Academy - Blog

Tutorials Details

Django Class-Based Views (CBVs): Complete Guide with Practical Examples

Django Class-Based Views (CBVs): Complete Guide with Practical Examples

October 19, 2026

Django Class-Based Views (CBVs): Complete Guide with Practical Examples

1. Introduction to Class-Based Views

Django provides two main approaches to writing views:

  1. Function-Based Views (FBVs): Views written using Python functions.

  2. Class-Based Views (CBVs): Views written using Python classes and methods.

Both approaches handle HTTP requests and return HTTP responses. Class-Based Views help organize reusable functionality and reduce repetitive code, especially in applications that perform common operations such as displaying lists, showing details, creating records, updating records, and deleting records.

By the end of this module, you will understand CBVs, their important methods, URL configuration, built-in generic views, and how to implement CRUD functionality.

2. What Is a Class-Based View?

A Class-Based View is a Python class that handles incoming HTTP requests through methods such as get() and post().

Example:

# students/views.py

from django.http import HttpResponse
from django.views import View

class WelcomeView(View):
    def get(self, request):
        return HttpResponse("Welcome to Django Class-Based Views!")

In this example:

  • View is Django's base class for class-based views.

  • WelcomeView is our custom view class.

  • get() handles GET requests.

  • request contains information about the incoming request.

  • HttpResponse sends a response back to the browser.

3. Configure the URL

Create or update the students/urls.py file:

from django.urls import path
from .views import WelcomeView

urlpatterns = [
    path("welcome/", WelcomeView.as_view(), name="welcome"),
]

The important part is:

WelcomeView.as_view()

Django uses as_view() to convert the class into a callable view that can be connected to a URL.

Make sure the project's main urls.py includes the app's URLs:

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path("admin/", admin.site.urls),
    path("students/", include("students.urls")),
]

Now run the development server:

python manage.py runserver

Open:

http://127.0.0.1:8000/students/welcome/

You should see the welcome message.

4. Understanding GET and POST Methods

CBVs can use different methods to handle HTTP request types.

from django.http import HttpResponse
from django.views import View

class StudentActionView(View):
    def get(self, request):
        return HttpResponse("Display student information")

    def post(self, request):
        return HttpResponse("Process submitted student information")
  • get() commonly displays pages and information.

  • post() commonly processes submitted forms or other changes.

  • put(), patch(), and delete() can also be implemented when required.

For ordinary HTML forms, GET is commonly used to display the form and POST to submit it. Always validate submitted data before saving it.

5. What Are Generic Class-Based Views?

Django includes generic CBVs for common web-development tasks. They reduce the amount of code you need to write.

Important generic views include:

Generic View Purpose
TemplateView Displays a template
ListView Displays a list of database records
DetailView Displays one record
CreateView Creates a record
UpdateView Updates an existing record
DeleteView Deletes a record
FormView Processes a form without requiring a model-based CRUD operation

6. TemplateView: Display a Template

Create a view in students/views.py:

from django.views.generic import TemplateView

class StudentHomeView(TemplateView):
    template_name = "students/home.html"

Create the template file:

templates/students/home.html

<!DOCTYPE html>
<html>
<head>
    <title>Student Home</title>
</head>
<body>
    <h1>Welcome to the Student Dashboard</h1>
    <p>This page is rendered using TemplateView.</p>
</body>
</html>

Configure the URL:

from django.urls import path
from .views import StudentHomeView

urlpatterns = [
    path("home/", StudentHomeView.as_view(), name="student_home"),
]

Visit /students/home/ to see the template.

7. ListView: Display Database Records

Suppose your application already has a Student model in students/models.py:

from django.db import models

class Student(models.Model):
    name = models.CharField(max_length=100)
    email = models.EmailField(unique=True)
    course = models.CharField(max_length=100)

    def __str__(self):
        return self.name

If this model is new or has changed, run:

python manage.py makemigrations
python manage.py migrate

Now create a list view:

from django.views.generic import ListView
from .models import Student

class StudentListView(ListView):
    model = Student
    template_name = "students/student_list.html"
    context_object_name = "students"
    ordering = ["name"]

Create templates/students/student_list.html:

<!DOCTYPE html>
<html>
<head>
    <title>Student List</title>
</head>
<body>
    <h1>All Students</h1>

    <ul>
        {% for student in students %}
            <li>
                {{ student.name }} -
                {{ student.email }} -
                {{ student.course }}
            </li>
        {% empty %}
            <li>No students found.</li>
        {% endfor %}
    </ul>
</body>
</html>

Add the URL:

path("list/", StudentListView.as_view(), name="student_list"),

ListView retrieves the records through the model and makes them available to the template. Here, context_object_name = "students" means the template uses the variable students.

8. DetailView: Display One Student

Add this view to students/views.py:

from django.views.generic import DetailView
from .models import Student

class StudentDetailView(DetailView):
    model = Student
    template_name = "students/student_detail.html"
    context_object_name = "student"

Create templates/students/student_detail.html:

<h1>Student Details</h1>

<p>Name: {{ student.name }}</p>
<p>Email: {{ student.email }}</p>
<p>Course: {{ student.course }}</p>

Configure the URL:

path(
    "detail/<int:pk>/",
    StudentDetailView.as_view(),
    name="student_detail",
),

The pk parameter identifies the record's primary key. By default, DetailView uses this value to retrieve the matching object and returns a 404 response if the object does not exist.

9. CreateView: Add a Student

Django's CreateView can generate and process a model form.

Add this view:

from django.urls import reverse_lazy
from django.views.generic import CreateView
from .models import Student

class StudentCreateView(CreateView):
    model = Student
    fields = ["name", "email", "course"]
    template_name = "students/student_form.html"
    success_url = reverse_lazy("student_list")

Create templates/students/student_form.html:

<h1>Student Form</h1>

<form method="post">
    {% csrf_token %}
    {{ form.as_p }}

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

Add the URL:

path("create/", StudentCreateView.as_view(), name="student_create"),

Django displays the form on a GET request and processes submitted form data on a POST request. If validation succeeds, the new student is saved and the browser is redirected to the student list.

10. UpdateView: Edit a Student

Add this view:

from django.urls import reverse_lazy
from django.views.generic import UpdateView
from .models import Student

class StudentUpdateView(UpdateView):
    model = Student
    fields = ["name", "email", "course"]
    template_name = "students/student_form.html"
    success_url = reverse_lazy("student_list")

Add the URL:

path(
    "update/<int:pk>/",
    StudentUpdateView.as_view(),
    name="student_update",
),

UpdateView retrieves the existing student using the primary key, pre-fills the form with the current values, validates submitted changes, and saves them when valid.

The same student_form.html can be used for both CreateView and UpdateView.

11. DeleteView: Delete a Student

Add this view:

from django.urls import reverse_lazy
from django.views.generic import DeleteView
from .models import Student

class StudentDeleteView(DeleteView):
    model = Student
    template_name = "students/student_confirm_delete.html"
    success_url = reverse_lazy("student_list")

Create templates/students/student_confirm_delete.html:

<h1>Delete Student</h1>

<p>Are you sure you want to delete {{ object.name }}?</p>

<form method="post">
    {% csrf_token %}
    <button type="submit">Confirm Delete</button>
</form>

<a href="{% url 'student_list' %}">Cancel</a>

Add the URL:

path(
    "delete/<int:pk>/",
    StudentDeleteView.as_view(),
    name="student_delete",
),

DeleteView displays a confirmation page on GET and performs the deletion on POST. Using a confirmation step helps prevent accidental deletion.

In real applications, restrict deletion to authorized users and consider whether records should be archived instead of permanently deleted.

12. Complete URL Configuration

Your students/urls.py can contain the following routes:

from django.urls import path

from .views import (
    StudentHomeView,
    StudentListView,
    StudentDetailView,
    StudentCreateView,
    StudentUpdateView,
    StudentDeleteView,
)

urlpatterns = [
    path("home/", StudentHomeView.as_view(), name="student_home"),
    path("list/", StudentListView.as_view(), name="student_list"),
    path("detail/<int:pk>/", StudentDetailView.as_view(), name="student_detail"),
    path("create/", StudentCreateView.as_view(), name="student_create"),
    path("update/<int:pk>/", StudentUpdateView.as_view(), name="student_update"),
    path("delete/<int:pk>/", StudentDeleteView.as_view(), name="student_delete"),
]

Make sure each imported class exists in students/views.py and that the main project URL configuration includes students.urls.

13. FBV vs CBV

Feature Function-Based View Class-Based View
Structure Python function Python class
Basic request handling Function logic Methods such as get() and post()
Reuse Can use helper functions and decorators Can use inheritance, mixins, and generic views
Simple custom logic Often straightforward May require more structure
Common CRUD tasks Usually require more manual code Generic views can reduce repetition

Neither approach is always better. Choose the one that makes the code easiest to understand, maintain, and test.

14. Common Errors and Solutions

Error 1: AttributeError or incorrect view configuration

Check that the class inherits from the correct Django view class and that the URL uses MyView.as_view().

Error 2: TemplateDoesNotExist

Verify the template path and the project's template settings. For example, check that templates/students/student_list.html exists and that the templates directory is configured correctly.

Error 3: NoReverseMatch

Confirm that the URL name used in success_url or a template matches the name declared in urls.py.

Error 4: OperationalError: no such table

Run migrations:

python manage.py makemigrations
python manage.py migrate

Error 5: 405 Method Not Allowed

Check which HTTP method your view supports and ensure that the form submits using the expected method.

Error 6: IntegrityError for a duplicate email

The example model declares email as unique. Submit a different email or display a clear validation error instead of attempting to save a duplicate.

15. Frequently Asked Questions

Q1. What is a Class-Based View in Django?

A CBV is a Python class that handles HTTP requests through methods such as get() and post().

Q2. Why do we use as_view()?

It converts the view class into a callable that Django can use in URL configuration.

Q3. What is TemplateView?

It is a generic view used to render a template.

Q4. What is the difference between ListView and DetailView?

ListView displays multiple objects, while DetailView displays one object.

Q5. What is CreateView used for?

It creates a new database record using a form.

Q6. What is UpdateView used for?

It updates an existing database record.

Q7. What is DeleteView used for?

It provides a confirmation page and handles deletion of an existing record.

Q8. What does reverse_lazy() do?

It resolves a named URL lazily, which is useful when setting URL destinations as class attributes.

Q9. Can CBVs handle POST requests?

Yes. A CBV can define post(), and Django's generic form views handle POST submissions through their built-in workflow.

Q10. Should every Django view be a CBV?

No. Use CBVs when they improve reuse or clarity. FBVs remain useful for simple or highly customized request handling.

16. Interview Questions and Answers

Q1. Explain FBV and CBV.

FBV uses a function to process a request. CBV uses a class with methods for handling different request types. Both can return HTTP responses.

Q2. What is the purpose of View?

django.views.View is the base class for creating custom class-based views.

Q3. How does ListView retrieve records?

When configured with a model or queryset, it retrieves the relevant objects and passes them to the template context.

Q4. What is the role of context_object_name?

It defines the name used to access the view's primary object or object list in the template context.

Q5. Why use reverse_lazy() for success_url?

It delays URL resolution until needed, avoiding premature resolution when the class is defined.

Q6. How can you protect a CBV?

Use appropriate authentication and authorization controls, such as LoginRequiredMixin and permission checks, and ensure the mixins are configured correctly.

Q7. What is a generic view?

A generic view is a reusable Django class that implements common web patterns, such as displaying lists or processing model forms.

17. Practical Assignment

Create a Student Management module using Class-Based Views.

Requirements:

  1. Create a Student model with name, email, and course fields.

  2. Display all students using ListView.

  3. Display an individual student's details using DetailView.

  4. Add new students using CreateView.

  5. Edit existing students using UpdateView.

  6. Delete students using DeleteView with a confirmation page.

  7. Configure all URLs with meaningful names.

  8. Test form validation and duplicate-email handling.

  9. Verify that all CRUD operations work correctly.

  10. Add suitable authentication and authorization before using the module in a real application.

18. Conclusion

Class-Based Views make Django applications more organized by grouping request-handling logic into classes. Built-in generic views such as ListView, DetailView, CreateView, UpdateView, and DeleteView can significantly reduce repetitive code.

Practice each view separately, understand how URLs connect to classes, and test the complete student workflow before moving forward.

Next Module: Django Authentication and User Login System — Login, Logout, Registration, and Access Control.