I've seen a lot of people on here and /r/django struggling with CBVs recently.
Just a reminder that you \*do not\* need to feel obligated to use CBVs. In real-world projects, the ratio of [FBV](https://docs.djangoproject.com/en/3.2/topics/http/views/)\-to-[CBV](https://docs.djangoproject.com/en/3.2/topics/class-based-views/intro/) is [essentially 50/50](https://dev.to/jackdlinke/modern-django-project-examples-58mm). CBVs are not objectively better or worse than FBVs, but they can be very difficult, especially for beginners. If you are struggling with CBVs, there are a couple things to consider:
* First, if do you choose to use CBVs there is a very detailed resource for familiarizing yourself with their intricacies: [https://ccbv.co.uk/](https://ccbv.co.uk/)
* Second, there is nothing unusual about struggling a bit with CBVs. They really can be complicated. Consider using FBVs to start with until you get more experience, or even skipping CBVs altogether (except if you're using DRF's ViewSet, for instance). I encourage you all to read through this excellent guide by [Luke Plant](https://twitter.com/spookylukey?lang=en) (one of Django's core developers) about why FBVs may be the better approach to Django Views. Even if you don't completely agree, he provides a number of useful insights and advice: [https://spookylukey.github.io/django-views-the-right-way/](https://spookylukey.github.io/django-views-the-right-way/)
That’s a great guide, thanks for sharing.
I’m curious for examples of situations where using a CBV is the best solution?
I’ve always found FBVs the most intuitive, but the prevalence of CBVs makes me think I’m missing something.
Can CBVs be used for generic functionality and FBVs used for the more bespoke functionality? Or are there CBVs, that can be adapted, for every operation a website needs? Excellent website link thanks.
Also, in case it helps anyone else, I keep this list of very simple FBV view starters handy in my notes. I’m sure it’s imperfect, but feel free to adapt to your needs:
views.py
from django.shortcuts import render
from django.shortcuts import get_object_or_404, HttpResponseRedirect
from django.template.response import TemplateResponse
from .forms import MyModelForm
from .models import MyModel
def create_view(request):
template = “create_view.html”
context = {}
form = MyModelForm(request.POST or None)
if request.method == ‘POST’:
if form.is_valid():
form.save()
return HttpResponseRedirect(‘/thanks/’)
context[“form”] = form
return TemplateResponse(request, template, context)
def list_view(request):
template = “list_view.html”
context = {}
context[“dataset”] = MyModel.objects.all()
return TemplateResponse(request, template, context)
def detail_view(request, id):
template = “detail_view.html”
context = {}
context[“data”] = MyModel.objects.get(id=id)
return TemplateResponse(request, template, context)
def update_view(request, id):
template = “update_view.html”
context = {}
obj = get_object_or_404(MyModel, id=id)
form = MyModelForm(request.POST or None, instance=obj)
if form.is_valid():
form.save()
return HttpResponseRedirect(“/” + id)
context[“form”] = form
return TemplateResponse(request, template, context)
def delete_view(request, id):
template = “delete_view.html”
context = {}
obj = get_object_or_404(MyModel, id=id)
if request.method == “POST”:
obj.delete()
return HttpResponseRedirect(“/”)
return TemplateResponse(request, template, context)
def htmx_example_view(request, arg):
template = “fragments/example.html”
context = {}
context[“key”] = “value”
return TemplateResponse(request, template, context)
def htmx_example_view2(request, arg):
“””if using django-htmx”””
if request.htmx:
template = “partial.html”
else:
template = “complete.html”
context = {}
context[“key”] = “value”
return TemplateResponse(request, template, context)
def paginated_list_view(request):
contact_list = Contact.objects.all()
paginator = Paginator(contact_list, 25) # Show 25 contacts per page.
page_number = request.GET.get(‘page’)
page_obj = paginator.get_page(page_number)
return render(request, ‘list.html’, {‘page_obj’: page_obj})
That Luke Plant blog post was a real game changer for me and allayed lots of paranoia I had that using FBV was somehow “not the proper way” or more amateurish…
I also found the predecessor to that post helpful: https://lukeplant.me.uk/blog/posts/my-approach-to-class-based-views/, which could be summarised as “if you don’t like GCBVs, write your own base Classes”.
Every Django begginer tutorial for a while was “start with FBV and then graduate to CBV”, and now there seems to be more growing consensus that either is fine (as mentioned by OP). I wonder if this is because of the rise of Flask/FastAPI…?
This video helped me understand generic views and class based views:
https://www.youtube.com/watch?v=uPRabryhv5k
He builds his own reusable views using classes, and then explains that what he just wrote is exactly the same idea behind Django’s CBVs.
Just what i’am looking for. Great shot, thanks.
HaHa. I logged in today just because the docs for Class Based views seem loaded with info while not answer most of my questions. But its just me for now.
Knowing OOP is a must for learning CBV
Is it bad practice to mix both CBV and FBV in your app? I usually use CBV for simple GET requests but for POST or DELETE requests, I use FBV.
ive read python crash courses whole all chapters but the last one and it was fbv then i started to read django for begginers by williams vincent and its cbv
idk should i read it or no becuz its really harder but kinda it feels more updated
and if no then what should i read
I didn’t find Luke Plant’s guide useful. It felt biased towards FBV rather than a fair comparison of each one advantages and uses.