← Back to Django Course | Chapter 9: Class-Based Views | Lesson 1 of 10

Introduction to Class-Based Views

A class-based view is like a recipe card that already knows how to cook several dishes, so you only change the ingredients instead of rewriting the whole recipe.

Function-Based vs Class-Based Views

A function-based view is a plain Python function that takes a request and returns a response. A class-based view is a Python class that does the same job but organizes the logic into methods like get() and post(), which Django calls automatically depending on the HTTP method used.

Note: Both approaches are valid Django; CBVs shine when a view needs to reuse logic across similar pages.

Example: Function-Based vs Class-Based Views

The function and the class both handle a GET request the same way, but the class organizes behavior by HTTP method name.

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


def home_fbv(request):
    return HttpResponse('Hello from a function-based view')


class HomeCBV(View):
    def get(self, request):
        return HttpResponse('Hello from a class-based view')
{# Django-only code -- models.py/views.py/urls.py/settings.py snippets, or template markup using Django template tags/variables -- can't run standalone via Judge0 or the browser preview, since it needs a real Django project. Only this course's pure-Python examples (example_lang == 'python', no Django imports) are actually runnable, so those still get the button below. #}

Wiring a CBV with as_view()

Class-based views cannot be referenced directly in urls.py because Django's URL resolver needs a callable function, not a class. Calling ClassName.as_view() returns a function that Django can call for every request, which internally creates an instance of the class and dispatches to the right method.

Warning: Forgetting the parentheses in .as_view() is a very common mistake — as_view is a method, not an attribute.

Example: Wiring a CBV with as_view()

HomeCBV.as_view() converts the class into something Django's URL dispatcher can call directly.

markup
from django.urls import path
from .views import HomeCBV

urlpatterns = [
    path('home/', HomeCBV.as_view(), name='home'),
]
{# Django-only code -- models.py/views.py/urls.py/settings.py snippets, or template markup using Django template tags/variables -- can't run standalone via Judge0 or the browser preview, since it needs a real Django project. Only this course's pure-Python examples (example_lang == 'python', no Django imports) are actually runnable, so those still get the button below. #}

Handling Multiple HTTP Methods

A class-based view can define separate methods for each HTTP verb it supports. Django's dispatch() method, inherited from View, automatically routes the incoming request to get(), post(), put(), delete(), and so on based on request.method.

Note: This keeps GET and POST logic visually separated instead of tangled in one big if/else block.

Example: Handling Multiple HTTP Methods

Django calls get() for GET requests and post() for POST requests on the same URL automatically.

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


class ContactCBV(View):
    def get(self, request):
        return HttpResponse('Show the contact form')

    def post(self, request):
        return HttpResponse('Contact form submitted')
{# Django-only code -- models.py/views.py/urls.py/settings.py snippets, or template markup using Django template tags/variables -- can't run standalone via Judge0 or the browser preview, since it needs a real Django project. Only this course's pure-Python examples (example_lang == 'python', no Django imports) are actually runnable, so those still get the button below. #}

Why Django Provides Generic CBVs

Writing a view to list objects, show one object, or handle a create/update/delete form follows the same pattern in almost every app. Django ships generic class-based views (ListView, DetailView, CreateView, UpdateView, DeleteView) that implement this pattern so you only supply the model and template.

Note: Later tutorials in this chapter cover each generic view individually.

Example: Why Django Provides Generic CBVs

This tiny class replaces a function view that would otherwise manually query Book.objects.all() and render a template.

markup
from django.views.generic import ListView
from .models import Book


class BookListView(ListView):
    model = Book
    template_name = 'books/book_list.html'
{# Django-only code -- models.py/views.py/urls.py/settings.py snippets, or template markup using Django template tags/variables -- can't run standalone via Judge0 or the browser preview, since it needs a real Django project. Only this course's pure-Python examples (example_lang == 'python', no Django imports) are actually runnable, so those still get the button below. #}
Common Mistakes
  1. Forgetting to call .as_view() when wiring a class-based view into urls.py, causing a TypeError.
  2. Overriding get() or post() but forgetting to call the parent implementation when it is still needed.
  3. Assuming a class-based view behaves identically to a function-based view without reading which methods it actually calls.
Chapter Summary
  • Class-based views (CBVs) package view logic as a Python class instead of a function.
  • Django provides built-in generic CBVs for common tasks like listing, showing, creating, updating, and deleting objects.
  • Every CBV is connected in urls.py using ClassName.as_view().
  • CBVs favor reuse through inheritance and mixins over copy-pasted function code.

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.