Class-Based Views
Explore Django's class-based views for reusable, object-oriented web request handling. This is a foundational concept in Python web development that professional developers rely on daily. The explanations below are written to be beginner-friendly while covering the depth and nuance that comes from real-world Python/Django experience. Take your time with each section and practice the examples
Class-Based Views (CBVs)
Class-based views provide an object-oriented way to organize code and reuse functionality. They're more powerful and flexible than function-based views.. This is an essential concept that every Python/Django developer must understand thoroughly. In professional development environments, getting this right can mean the difference between code that works reliably and code that breaks in production. The following sections break this down into clear, digestible pieces with practical examples you can try immediately
Common CBVs
from django.views.generic import ListView, DetailView, CreateView, UpdateView, DeleteView
from django.contrib.auth.mixins import LoginRequiredMixin
from django.urls import reverse_lazy
from .models import Post, Category
from .forms import PostForm
# List View
class PostListView(ListView):
model = Post
template_name = 'blog/post_list.html'
context_object_name = 'posts'
paginate_by = 10
ordering = ['-published_date']
def get_queryset(self):
"""Filter to only published posts"""
return Post.objects.filter(published_date__isnull=False)
def get_context_data(self, **kwargs):
"""Add extra context data"""
context = super().get_context_data(**kwargs)
context['categories'] = Category.objects.all()
return context
# Detail View
class PostDetailView(DetailView):
model = Post
template_name = 'blog/post_detail.html'
context_object_name = 'post'
def get_object(self):
"""Get the post or return 404"""
return get_object_or_404(Post, pk=self.kwargs['pk'])
# Create View
class PostCreateView(LoginRequiredMixin, CreateView):
model = Post
form_class = PostForm
template_name = 'blog/post_form.html'
success_url = reverse_lazy('post_list')
def form_valid(self, form):
"""Set the author before saving"""
form.instance.author = self.request.user
return super().form_valid(form)
# Update View
class PostUpdateView(LoginRequiredMixin, UpdateView):
model = Post
form_class = PostForm
template_name = 'blog/post_form.html'
def get_success_url(self):
"""Redirect to the updated post"""
return reverse_lazy('post_detail', kwargs={'pk': self.object.pk})
# Delete View
class PostDeleteView(LoginRequiredMixin, DeleteView):
model = Post
template_name = 'blog/post_confirm_delete.html'
success_url = reverse_lazy('post_list')
# Custom CBV with mixins
from django.contrib.auth.mixins import UserPassesTestMixin
class UserPostListView(LoginRequiredMixin, ListView):
model = Post
template_name = 'blog/user_posts.html'
context_object_name = 'posts'
def get_queryset(self):
"""Show only user's posts"""
return Post.objects.filter(author=self.request.user)
class PostUpdateView(LoginRequiredMixin, UserPassesTestMixin, UpdateView):
model = Post
form_class = PostForm
template_name = 'blog/post_form.html'
def test_func(self):
"""Check if user is the author of the post"""
post = self.get_object()
return self.request.user == post.author