Django & Flask Topic
Django Class-Based Views (CBVs)
This is one of the most powerful features of Django that can dramatically improve your productivity once you understand the concepts.
What are Class-Based Views?
Class-Based Views are an alternative to Function-Based Views (FBVs) that use Python classes instead of functions. They provide a structured way to handle HTTP requests and are perfect for common web development patterns.
Core CBVs Hierarchy
text
View (Base class)
├── TemplateView
├── RedirectView
├── FormView
└── Generic Display Views
├── ListView
└── DetailView
└── Generic Editing Views
├── CreateView
├── UpdateView
└── DeleteView
1. The Base View Class
Purpose: Foundation for all other CBVs
python
from django.views import View
from django.http import HttpResponse
class MyView(View):
def get(self, request, *args, **kwargs):
return HttpResponse("GET request handled!")
def post(self, request, *args, **kwargs):
return HttpResponse("POST request handled!")
def put(self, request, *args, **kwargs):
return HttpResponse("PUT request handled!")
URL configuration:
python
from django.urls import path
from .views import MyView
urlpatterns = [
path('my-view/', MyView.as_view(), name='my-view'),
]
2. TemplateView
Purpose: Render a template without any complex logic
python
from django.views.generic import TemplateView
class HomePageView(TemplateView):
template_name = "home.html"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['latest_articles'] = Article.objects.all()[:5]
context['title'] = "Welcome to Our Site"
return context
3. ListView
Purpose: Display a list of objects
python
from django.views.generic import ListView
from .models import Article
class ArticleListView(ListView):
model = Article
template_name = "articles/article_list.html"
context_object_name = "articles" # Default would be 'object_list'
paginate_by = 10
ordering = ['-published_date']
def get_queryset(self):
# Custom filtering
queryset = super().get_queryset()
category = self.request.GET.get('category')
if category:
queryset = queryset.filter(category__name=category)
return queryset
Template context: object_list, articles (if context_object_name is set)
4. DetailView
Purpose: Display details of a single object
python
from django.views.generic import DetailView
from .models import Article
class ArticleDetailView(DetailView):
model = Article
template_name = "articles/article_detail.html"
context_object_name = "article" # Default would be 'object'
slug_field = "slug" # Use slug instead of pk
slug_url_kwarg = "slug" # URL parameter name
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['related_articles'] = Article.objects.filter(
category=self.object.category
).exclude(pk=self.object.pk)[:3]
return context
URL pattern:
python
path('article/<slug:slug>/', ArticleDetailView.as_view(), name='article-detail')
5. CreateView
Purpose: Handle form submission for creating new objects
python
from django.views.generic import CreateView
from django.urls import reverse_lazy
from .models import Article
from .forms import ArticleForm
class ArticleCreateView(CreateView):
model = Article
form_class = ArticleForm
template_name = "articles/article_form.html"
success_url = reverse_lazy('article-list')
def form_valid(self, form):
# Auto-set the author to current user
form.instance.author = self.request.user
return super().form_valid(form)
6. UpdateView
Purpose: Handle form submission for updating existing objects
python
from django.views.generic import UpdateView
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib import messages
class ArticleUpdateView(LoginRequiredMixin, UpdateView):
model = Article
form_class = ArticleForm
template_name = "articles/article_form.html"
def get_success_url(self):
messages.success(self.request, "Article updated successfully!")
return reverse('article-detail', kwargs={'slug': self.object.slug})
def get_queryset(self):
# Only allow authors to edit their own articles
queryset = super().get_queryset()
return queryset.filter(author=self.request.user)
7. DeleteView
Purpose: Handle object deletion with confirmation
python
from django.views.generic import DeleteView
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
class ArticleDeleteView(LoginRequiredMixin, UserPassesTestMixin, DeleteView):
model = Article
template_name = "articles/article_confirm_delete.html"
success_url = reverse_lazy('article-list')
def test_func(self):
# Only allow authors to delete their articles
article = self.get_object()
return article.author == self.request.user
def delete(self, request, *args, **kwargs):
messages.success(request, "Article deleted successfully!")
return super().delete(request, *args, **kwargs)
URL Configuration for All Views
python
from django.urls import path
from .views import (
ArticleListView,
ArticleDetailView,
ArticleCreateView,
ArticleUpdateView,
ArticleDeleteView
)
urlpatterns = [
path('', ArticleListView.as_view(), name='article-list'),
path('article/<slug:slug>/', ArticleDetailView.as_view(), name='article-detail'),
path('article/new/', ArticleCreateView.as_view(), name='article-create'),
path('article/<slug:slug>/edit/', ArticleUpdateView.as_view(), name='article-update'),
path('article/<slug:slug>/delete/', ArticleDeleteView.as_view(), name='article-delete'),
]
Using Mixins for Common Functionality
Mixins are reusable pieces of functionality that can be combined with CBVs:
python
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
class StaffRequiredMixin(UserPassesTestMixin):
def test_func(self):
return self.request.user.is_staff
class AdminArticleCreateView(LoginRequiredMixin, StaffRequiredMixin, CreateView):
model = Article
fields = ['title', 'content', 'category']
template_name = "articles/admin_article_form.html"
success_url = reverse_lazy('article-list')
Key Advantages of CBVs
-
Code Reuse: Inherit and extend functionality
-
Structure: Consistent patterns for common tasks
-
Built-in Features: Pagination, forms, success URLs
-
Mixins: Composable behavior
-
Less Boilerplate: Common patterns are handled automatically
Common Methods to Override
-
get_queryset()- Customize the object list -
get_context_data()- Add extra context to templates -
form_valid()- Custom behavior when form is valid -
get_success_url()- Determine where to redirect after success -
test_func()- For permission checks with UserPassesTestMixin
When to Use CBVs vs FBVs
Use CBVs for:
-
CRUD operations (Create, Read, Update, Delete)
-
Displaying lists or details of objects
-
Forms with standard patterns
-
When you need pagination, searching, filtering
Use FBVs for:
-
Very simple views
-
Highly custom behavior that doesn't fit CBV patterns
-
API endpoints (often better with DRF)
-
When the CBV would require too many overrides
This foundation will help you write cleaner, more maintainable Django code while significantly reducing boilerplate!
Comments (0)
No comments yet. Be the first to comment!