Function-based views vs. class-based views
Introduction
Django Rest Framework (DRF) provides two main ways to define views: Function-based views (FBVs) and Class-based views (CBVs). Each approach has its own advantages and use cases. This tutorial will explain the differences between FBVs and CBVs, their pros and cons, and provide practical examples of how to use each.
Prerequisites
Before you start, ensure you have a DRF project set up. If not, please refer to our previous tutorial on setting up a DRF project.
Function-based Views (FBVs)
Definition
Function-based views are simple functions that take a web request and return a web response. They provide a straightforward way to define views in Django and DRF.
Example Use Case: Simple Book API
Let’s create a simple API to manage books using function-based views.
Step 1: Define the Model
# myapp/models.py
from django.db import models
class Book(models.Model):
title = models.CharField(max_length=100)
author = models.CharField(max_length=100)
published_date = models.DateField()
def __str__(self):
return self.title
Step 2: Create a Serializer
# myapp/serializers.py
from rest_framework import serializers
from .models import Book
class BookSerializer(serializers.ModelSerializer):
class Meta:
model = Book
fields = ['id', 'title', 'author', 'published_date']
Step 3: Define Function-based Views
# myapp/views.py
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework import status
from .models import Book
from .serializers import BookSerializer
@api_view(['GET', 'POST'])
def book_list(request):
if request.method == 'GET':
books = Book.objects.all()
serializer = BookSerializer(books, many=True)
return Response(serializer.data)
elif request.method == 'POST':
serializer = BookSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
@api_view(['GET', 'PUT', 'DELETE'])
def book_detail(request, pk):
try:
book = Book.objects.get(pk=pk)
except Book.DoesNotExist:
return Response(status=status.HTTP_404_NOT_FOUND)
if request.method == 'GET':
serializer = BookSerializer(book)
return Response(serializer.data)
elif request.method == 'PUT':
serializer = BookSerializer(book, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
elif request.method == 'DELETE':
book.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
Step 4: Configure URLs
# myapp/urls.py
from django.urls import path
from .views import book_list, book_detail
urlpatterns = [
path('books/', book_list, name='book-list'),
path('books/<int:pk>/', book_detail, name='book-detail'),
]
Pros and Cons of Function-based Views
Pros
- Simplicity: Easy to understand and write.
- Explicitness: Clearly shows the flow of data and logic.
Cons
- Reusability: Limited reusability and harder to extend.
- Scalability: Can become cumbersome for complex views with multiple HTTP methods.
Class-based Views (CBVs)
Definition
Class-based views use Python classes to encapsulate the view logic. They provide a more structured and reusable way to define views in Django and DRF.
Example Use Case: Simple Book API
Let’s create the same API to manage books using class-based views.
Step 1: Define the Model
Same as the FBV example above.
Step 2: Create a Serializer
Same as the FBV example above.
Step 3: Define Class-based Views
# myapp/views.py
from rest_framework import generics
from .models import Book
from .serializers import BookSerializer
class BookListCreate(generics.ListCreateAPIView):
queryset = Book.objects.all()
serializer_class = BookSerializer
class BookRetrieveUpdateDestroy(generics.RetrieveUpdateDestroyAPIView):
queryset = Book.objects.all()
serializer_class = BookSerializer
Step 4: Configure URLs
# myapp/urls.py
from django.urls import path
from .views import BookListCreate, BookRetrieveUpdateDestroy
urlpatterns = [
path('books/', BookListCreate.as_view(), name='book-list'),
path('books/<int:pk>/', BookRetrieveUpdateDestroy.as_view(), name='book-detail'),
]
Pros and Cons of Class-based Views
Pros
- Reusability: Easy to extend and reuse code.
- Scalability: Better suited for complex views with multiple HTTP methods.
- Built-in Mixins: DRF provides mixins to handle common patterns, reducing boilerplate code.
Cons
- Complexity: Slightly more complex to understand for beginners.
- Less Explicit: The flow of logic can be less explicit compared to FBVs.
Conclusion
Both Function-based views and Class-based views have their place in Django Rest Framework. FBVs are great for simple, straightforward views, while CBVs provide a more structured and reusable approach for complex views. Understanding both approaches allows you to choose the best tool for the task at hand.
Tags: Function-based views vs. Class-based views in DRF
, DRF views tutorial
, how to use FBVs and CBVs in Django
, Django API development