Django CBV - Class-Based Views, Mixins, Generic Views

DjangoDjango CBVFree Lesson

Advertisement

Introduction

Class-Based Views (CBVs) in Django provide an object-oriented approach to handling HTTP requests. They offer better code reuse through inheritance and mixins.

Basic Class-Based Views

from django.views import View
from django.shortcuts import render, redirect
from django.http import JsonResponse
from .models import Article
from .forms import ArticleForm

class ArticleListView(View):
    def get(self, request):
        articles = Article.objects.all()
        return render(request, 'articles/list.html', {'articles': articles})
    
    def post(self, request):
        form = ArticleForm(request.POST)
        if form.is_valid():
            form.save()
            return redirect('article_list')
        return render(request, 'articles/form.html', {'form': form})

class ArticleDetailView(View):
    def get(self, request, pk):
        try:
            article = Article.objects.get(pk=pk)
            return render(request, 'articles/detail.html', {'article': article})
        except Article.DoesNotExist:
            return JsonResponse({'error': 'Not found'}, status=404)

Generic Views

from django.views.generic import ListView, DetailView, CreateView, UpdateView, DeleteView
from django.urls import reverse_lazy
from .models import Article
from .forms import ArticleForm

class ArticleListView(ListView):
    model = Article
    template_name = 'articles/list.html'
    context_object_name = 'articles'
    paginate_by = 10
    queryset = Article.objects.filter(status='published')

class ArticleDetailView(DetailView):
    model = Article
    template_name = 'articles/detail.html'
    context_object_name = 'article'

class ArticleCreateView(CreateView):
    model = Article
    form_class = ArticleForm
    template_name = 'articles/form.html'
    success_url = reverse_lazy('article_list')

class ArticleUpdateView(UpdateView):
    model = Article
    form_class = ArticleForm
    template_name = 'articles/form.html'
    success_url = reverse_lazy('article_list')

class ArticleDeleteView(DeleteView):
    model = Article
    template_name = 'articles/confirm_delete.html'
    success_url = reverse_lazy('article_list')

Mixins

from django.views.generic import ListView
from django.core.paginator import Paginator
from django.http import JsonResponse

class PaginationMixin:
    paginate_by = 10
    
    def get_paginate_by(self, queryset):
        return self.request.GET.get('page_size', self.paginate_by)

class JSONResponseMixin:
    def render_to_json_response(self, context, **response_kwargs):
        return JsonResponse(self.get_context_data(**response_kwargs))

class ArticleListView(PaginationMixin, ListView):
    model = Article
    
    def get_queryset(self):
        return Article.objects.filter(author=self.request.user)

class MultipleObjectMixin:
    def get_queryset(self):
        return super().get_queryset().filter(is_active=True)

URLs Configuration

# urls.py
from django.urls import path
from . import views

urlpatterns = [
    path('articles/', views.ArticleListView.as_view(), name='article_list'),
    path('articles/<int:pk>/', views.ArticleDetailView.as_view(), name='article_detail'),
    path('articles/create/', views.ArticleCreateView.as_view(), name='article_create'),
    path('articles/<int:pk>/edit/', views.ArticleUpdateView.as_view(), name='article_update'),
    path('articles/<int:pk>/delete/', views.ArticleDeleteView.as_view(), name='article_delete'),
]

Practice Problems

  1. Create a View that returns JSON for API requests and HTML for regular requests
  2. Implement a paginated list view that allows sorting by different fields
  3. Build a CreateView with a custom form that pre-fills data from the request
  4. Create a mixin that adds caching functionality to any view
  5. Implement a view that handles both GET and POST with different logic

Advertisement

Need Expert Python Help?

Get personalized tutoring, project support, or professional consulting.

Advertisement