Class-Based Views
A class-based view (CBV) in Django is a view written as a Python class instead of a function — it uses methods like get() and post() to handle each HTTP verb, and it lets you reuse and extend view behaviour through inheritance and mixins.
Learn Class-Based Views in our free Django course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick reference.
Part of the free Django course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
You'll meet Django's base View class, render pages with TemplateView, pass data via get_context_data, and learn when a CBV beats a plain function.
Every class-based view inherits from django.views.View . Instead of one function with branching logic, you write a separate method for each HTTP verb: get() for GET requests, post() for POST, and so on. Each method receives the request and returns a response — exactly like a function-based view, just organised by verb.
Here is a real Django class-based view. Notice that the URL points at .as_view() , not the class itself:
Most pages just render a template with some data. Django's TemplateView handles that for you: set template_name , then override get_context_data() to supply the variables your template needs. You never write get() yourself — TemplateView does it.
In home.html you would then read those values with template tags such as the title variable and a loop over the features list. The key rule: always call super().get_context_data(**kwargs) first so you keep the context Django already built.
Neither style is always right. Reach for a function-based view when the logic is short, custom, and read top-to-bottom in one place. Reach for a class-based view when you want to reuse behaviour across pages, handle several HTTP verbs cleanly, or build on Django's generic views.
A mixin is a class that supplies one slice of behaviour, meant to be combined with a view through multiple inheritance. You list mixins before the base view so their behaviour wraps around it. For example, LoginRequiredMixin blocks anonymous users before your get() ever runs:
Fill in the blank so the URL helper calls the right classmethod that turns a view class into a callable Django can route to.
You passed the class itself to path() instead of the callable it produces.
✅ Fix: call .as_view() in the URL — GreetingView.as_view() , not GreetingView .
You overrode get_context_data but never called super() , so the base context was lost.
✅ Fix: start with context = super().get_context_data(**kwargs) before adding your own keys.
You named the method something other than the HTTP verb — for example get_request instead of get .
✅ Fix: name handler methods exactly after the verb: get , post , put , delete .
Build a small View subclass that answers both GET and POST, then route a fake request through your own dispatch to prove it picks the right method.
Lesson 12 complete — you can write class-based views!
You now know how the base View class dispatches GET and POST, how .as_view() wires a class into a URL, how TemplateView and get_context_data render data, and when a CBV beats a function — plus how mixins layer reusable behaviour.
🚀 Up next: Generic Views — let Django write the list, detail, create, and update views for you.
Practice quiz
In a class-based view, which method handles a GET request?
- get()
- handle_get()
- on_get()
- render()
Answer: get(). A CBV uses a method named after each HTTP verb, so get() handles GET requests.
Which base class do most class-based views inherit from?
- models.Model
- forms.Form
- django.views.View
- TemplateBase
Answer: django.views.View. django.views.View is the base class for class-based views.
What must you call in urls.py to route a class-based view?
- MyView.render()
- MyView.as_view()
- MyView.dispatch()
- MyView()
Answer: MyView.as_view(). .as_view() returns the callable the URL resolver needs to dispatch requests.
Which generic view renders a template with minimal code?
- ListView
- FormView
- RedirectView
- TemplateView
Answer: TemplateView. TemplateView renders a template; you set template_name and override get_context_data.
What must get_context_data() call first to keep the base context?
- self.render()
- self.get()
- super().get_context_data(**kwargs)
- self.dispatch()
Answer: super().get_context_data(**kwargs). Calling super() first preserves the context Django already built.
What error happens if you pass the class instead of .as_view() to path()?
- TypeError: view must be a callable
- 404 Not Found
- ImportError
- It works fine
Answer: TypeError: view must be a callable. The URL resolver needs a callable; the class itself is not one without .as_view().
What is a mixin in class-based views?
- A migration file
- A URL converter
- A template tag
- A small class adding one reusable behavior via multiple inheritance
Answer: A small class adding one reusable behavior via multiple inheritance. Mixins supply one slice of behavior to combine with a view through inheritance.
Where do you list a mixin like LoginRequiredMixin?
- After the base view
- Before the base view
- In settings.py
- In the template
Answer: Before the base view. Mixins are listed before the base view so their behavior wraps the view.
What causes a 405 Method Not Allowed in a CBV?
- Forgetting super()
- Wrong template_name
- Naming a handler method something other than the HTTP verb
- Missing as_view()
Answer: Naming a handler method something other than the HTTP verb. Handler methods must be named exactly after the verb (get, post, put, delete).
When is a function-based view a good choice over a CBV?
- Short, custom, one-off logic read top to bottom
- Standard CRUD pages
- Reusing behavior across many pages
- Building on generic views
Answer: Short, custom, one-off logic read top to bottom. FBVs are simpler and explicit for short, one-off, or unusual logic.