Django class based vs function based views

By on 28 February 2023

This post first appeared as an email on our friends list. We decided to publish it here because the question is still commonly asked 🤔


The other day I did a presentation on Django class based vs function based views. (Warning: this post is opinionated 😃)

Also if you’re not into Django don’t stop reading just yet, because there are parallels with common software design patterns you might find interesting.

Here is a summary of interesting things I presented (and credit to Luke Plant’s Django Views the Right Way for cementing what I already started to sense using both types of views, and Ryan for sending it my way):

– Class based views (CBVs from here on) are great for simple use cases (e.g.: CRUD or create-read-update-delete), but going beyond that is tricky, because you have to know what methods to override. Luckily there is Classy Class-Based Views but in practice you end up having to learn a monstrous API (that is, reading a lot of source code of parent classes and mixins) to make sense of it all. Also as these CBVs are generic, code is less explicit (e.g. the use of self.kwargs – what does this hold?!)

– So you need to know the signature of the thing you override (attribute or method). For example, if you override get_context_data() to pass extra data to a template you need to know:

    – It takes **kwargs
    – You have to call the parent’s get_context_data() using super()
    – You have to return the context dictionary.

Compare that to a function based view where this dictionary is already passed into the response object, you literally have to add another key/value pair to this dictionary, a single line of code change. Much more transparent.

– Overall, I find function based views easier to reason about. It shows what a view actually is (!): a function that receives a web request and returns a web response. CBVs hide this from you, which makes them more implicit, and as the Zen of Python says: explicit is better than implicit.

– CBVs leverage multiple inheritance and mixins. Inheritance trees can be hard to follow (and they tend to get quite deep with CBVs), because there are more dependencies and mixins (common code you “plugin” to a bunch of classes) that makes the number of permutations even greater (and can even lead to code clashes).

Again functions are more straightforward, easier to isolate and test (see this article). To learn more about the limitation of inheritance you might want to read The Composition Over Inheritance Principle.

What about code duplication across function based views? Well, nothing stops you from extracting duplicated code out into helper functions or use decorators which are an elegant pattern for this (e.g.: in Django you can “lock down” your views with @login_required)

The Zen of Python’s simple is better than complex axiom is probably my favorite and for that reason I am sticking with function based views for now. What about you?

– Bob


This is the sort of stuff we discuss on our weekly Code Clinic calls inside PDM.

However the calls are not even the main part of the program. It’s the 1:1 coaching that is shaving off years of struggle and procrastination for Pythonistas we work with.

People credit PDM as a (if not the) major stepping stone in their careers. So if you’re ready to take your Python developer journey to the next level, check out our program here.

Want a career as a Python Developer but not sure where to start?