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.