In this article, we’ll explore how Class-Based Views (CBVs) can be used to build clean, reusable APIs instead of rendering templates.
💡 What Are Class-Based Views?
Class-Based Views (CBVs) allow you to organize request-handling logic using Python classes instead of functions. They provide structure and reusability for common API operations such as fetching lists, retrieving single records, creating, updating, and deleting data.
Example – converting FBV to CBV:
Function Based View
from django.http import JsonResponse
def home(request):
return JsonResponse({"message" : Welcome to My Blog API"})
Class Based view
from django.views import View
from django.http import JsonResponse
class HomeView(View):
def get(self, request):
return JsonResponse({"message": "Welcome to My Blog API!"})
And in urls.py
from django.urls import path
from .views import HomeView
urlpatterns = [
path('', HomeView.as_view(), name='home'),
]
as_view() converts the class into a callable function that Django can handle.
⚙️ Example: API CRUD Using CBVs
Let's say we have a simple Post models:
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
We’ll create CBVs for each CRUD operation and return JSON responses.
1️⃣ ListView – Get All Posts
class PostListView(View):
def get(self, request):
posts = list(Post.objects.values())
return JsonResponse({"posts": posts})
2️⃣ DetailView – Get a Single Post
class PostDetailView(View):
def get(self, request, pk):
try:
post = Post.objects.values().get(id=pk)
return JsonResponse({"post": post})
except Post.DoesNotExist:
return HttpResponseNotFound(JsonResponse({"error": "Post not found"}))
3️⃣ CreateView – Add a New Post
@method_decorator(csrf_exempt, name='dispatch')
class PostCreateView(View):
def post(self, request):
data = json.loads(request.body)
post = Post.objects.create(title=data.get('title'), content=data.get('content'))
return JsonResponse({"id": post.id, "message": "Post created successfully"}, status=201)
4️⃣ UpdateView – Edit an Existing Post
@method_decorator(csrf_exempt, name='dispatch')
class PostUpdateView(View):
def put(self, request, pk):
try:
post = Post.objects.get(id=pk)
data = json.loads(request.body)
post.title = data.get('title', post.title)
post.content = data.get('content', post.content)
post.save()
return JsonResponse({"message": "Post updated successfully"})
except Post.DoesNotExist:
return JsonResponse({"error": "Post not found"}, status=404)
5️⃣ DeleteView – Remove a Post
@method_decorator(csrf_exempt, name='dispatch')
class PostDeleteView(View):
def delete(self, request, pk):
try:
post = Post.objects.get(id=pk)
post.delete()
return JsonResponse({"message": "Post deleted successfully"})
except Post.DoesNotExist:
return JsonResponse({"error": "Post not found"}, status=404)
🧠 Why CBVs Are Great for APIs
- Cleaner, more structured code.
- Each HTTP method has its own function (get, post, put, delete).
- Easy to extend and reuse logic using inheritance.
- Plays nicely with Django REST Framework if you decide to scale up.
⚡ Best Practices
Always return JSON for frontend consumption.
Use csrf_exempt carefully or rely on proper CSRF tokens for POST/PUT requests.
Validate input data before saving.
Use Django REST Framework for complex APIs with authentication, pagination, and serializers.
🏆 Summary
CBVs can be used not only for HTML rendering but also for clean API design.
Each request type (GET, POST, PUT, DELETE) can be handled within a single class.
Use CBVs for modular, maintainable, and testable backend APIs.
Top comments (0)