100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Python

Class-Based Views

Understand how Django's class-based views (CBVs) organize request handling into methods on a class, and how generic CBVs and mixins reduce boilerplate for common patterns like CRUD.

Views & URLsIntermediate9 min readJul 10, 2026
Analogies

What Is a Class-Based View?

A class-based view (CBV) organizes request handling as methods on a Python class instead of a single function: get() handles GET requests, post() handles POST requests, and so on, dispatched automatically by the View base class's as_view() and dispatch() machinery. When Django resolves a URL to a CBV, as_view() returns a function that instantiates the class per request and calls dispatch(), which looks at request.method and routes to the matching method by name. This means the method-branching that FBVs do manually with if/elif is handled for you automatically by the framework.

🏏

Cricket analogy: It's like a specialist all-rounder such as Ravindra Jadeja who bats, bowls, and fields, with the team management (dispatch) automatically deciding which skill (method) to call on depending on the match situation (HTTP method).

Generic Class-Based Views

Django ships a library of generic CBVs — ListView, DetailView, CreateView, UpdateView, DeleteView, and TemplateView — that implement common CRUD patterns with minimal code. For example, ListView only requires you to set model and template_name (or override get_queryset) and it automatically handles pagination via paginate_by, context population, and template rendering. This dramatically reduces boilerplate for standard listing and detail pages compared to writing the equivalent FBV by hand, though it requires learning each generic view's attribute names and method resolution order (MRO).

🏏

Cricket analogy: It's like using a pre-set fielding template for a T20 powerplay instead of placing each fielder individually every match; you just tweak a couple of positions (attributes) and the standard setup (ListView) handles the rest.

python
from django.views.generic import ListView, DetailView, CreateView
from django.urls import reverse_lazy
from .models import Article

class ArticleListView(ListView):
    model = Article
    template_name = 'articles/list.html'
    context_object_name = 'articles'
    paginate_by = 20

    def get_queryset(self):
        return Article.objects.filter(published=True).order_by('-created_at')

class ArticleCreateView(CreateView):
    model = Article
    fields = ['title', 'body', 'published']
    template_name = 'articles/form.html'
    success_url = reverse_lazy('article_list')

Mixins for Reusable Behavior

CBVs support multiple inheritance, so Django provides mixins like LoginRequiredMixin, PermissionRequiredMixin, and UserPassesTestMixin that you stack alongside a generic view class to layer in cross-cutting behavior without rewriting logic. Because Python resolves methods via the MRO (Method Resolution Order), mixin order in the class definition matters: access-control mixins are conventionally listed first (leftmost) so their dispatch() or test logic runs before the generic view's own dispatch(). This composability is the main advantage CBVs have over FBVs for larger applications with many similar views.

🏏

Cricket analogy: It's like adding a fielding-restriction rule (mixin) on top of the base T20 rules (base class) — the powerplay restriction layers onto the standard game without rewriting the whole rulebook.

Use as_view() when mapping a CBV in urls.py — e.g., path('articles/', ArticleListView.as_view(), name='article_list') — because as_view() returns the actual callable Django's URL resolver needs; you never map the class itself.

Mixin order is not cosmetic: placing LoginRequiredMixin after a generic view class in the MRO can cause the permission check to run too late or not at all, silently exposing a view you intended to protect.

  • CBVs dispatch HTTP methods to same-named methods (get(), post(), etc.) automatically via View.dispatch().
  • Generic CBVs like ListView, DetailView, CreateView, UpdateView, and DeleteView implement common CRUD flows with minimal configuration.
  • Mixins (LoginRequiredMixin, PermissionRequiredMixin) add reusable cross-cutting behavior via multiple inheritance.
  • Mixin ordering matters because Python resolves methods left-to-right through the MRO — access-control mixins go first.
  • Always map CBVs in urls.py using ClassName.as_view(), never the raw class.
  • CBVs trade some readability/transparency for significant boilerplate reduction on repetitive CRUD views.
  • Overriding get_queryset(), get_context_data(), or form_valid() is the standard way to customize generic CBV behavior.

Practice what you learned

Was this page helpful?

Topics covered

#Python#DjangoStudyNotes#WebDevelopment#ClassBasedViews#Class#Based#Views#View#OOP#StudyNotes#SkillVeris