Understanding APIView, ModelViewSet and ViewSet in Django Rest Framework (DRF)
When building REST APIs with Django Rest Framework (DRF), choosing the right view class for API endpoints can be confusing. DRF provides…
Understanding APIView, ModelViewSet and ViewSet in Django Rest Framework (DRF)
When building REST APIs with Django Rest Framework (DRF), choosing the right view class for API endpoints can be confusing. DRF provides several classes for API development, each offering different levels of abstraction and flexibility. Three key classes — APIView, ModelViewSet, and ViewSet — offer the lowest levels of abstraction for handling HTTP requests and serve as the foundation for DRF’s more generic classes.
In this article, we’ll explore these three essential classes in detail, highlight their differences, and discuss scenarios where each is best suited.
APIView
APIView is a foundational class in DRF for handling HTTP requests, closely resembling Django’s View class. It provides HTTP method handlers like get(), post(), put(), and delete(), offering maximum control over request handling. Unlike other DRF view classes, APIView doesn’t require serializers, querysets, or default CRUD behavior — each handler is defined and configured manually.
Below is an example of an APIView, where get and post methods are explicitly defined, allowing full control over response structure and data processing.
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
class CustomAPIView(APIView):
def get(self, requests, *args, **kwargs):
data = {'message': 'Get request'}
return Response(data, status=status.HTTP_200_OK)
def post(self, requests, *args, **kwargs):
data={"message": "Post request"}
return Response(data, status=status.HTTP_201_CREATED)
Viewset
ViewSet is a DRF class designed to organize multiple HTTP actions — such as list(), retrieve(), update(), partial_update(), and create()— into a single class, making it more streamlined than using APIView for multiple endpoints. Notably, ViewSet doesn’t assume CRUD functionality but allows for defining custom actions for each HTTP method as needed. It isn’t tied to a specific model or queryset, making it ideal for custom methods or complex logic beyond CRUD. It also simplifies specifying a designed endpoint.
Here’s an example of a ViewSet in use:
from rest_framework import viewsets
from rest_framework.response import Response
from rest_framework.decorators import action
class CustomViewset(viewsets.ViewSet):
@action(methods=['GET'], detail=False, url_path='user')
def get_user(self, requests, *args, **kwargs):
data = {'message': "get_user"}
return Response(data, status=status.HTTP_200_OK)
def retrieve(self, requests, pk=None, *args, **kwargs):
data = {'message': f"Retrieve item {pk}"}
return Response(data, status=status.HTTP_200_OK)
The example includes a custom HTTP action method and a modified built-in action method. ViewSet is configured to recognize its built-in actions automatically. For any custom HTTP action, such as get_user in the example, the @action decorator is used to register it as an endpoint. The @action decorator cannot be used with built-in methods, as each of these is tied to specific behavior.
ModelViewSet
ModelViewSet is a high-level, fully-featured class that automates CRUD operations for a given model. It provides standard actions like list(), create(), retrieve(), update(), and destroy() out of the box, making it ideal for quickly building REST APIs that directly map to models and require full CRUD functionality.
However, ModelViewSet is not designed for custom logic; it requires both a model and serializer class to handle data structure and response format. This makes it a strong choice for straightforward CRUD endpoints, especially when time is limited.
Here’s an example of a ModelViewSet implementation:
from rest_framework import viewsets
from .models import CustomModel
from .serializers import CustomSerializer
class CustomModelViewset(viewsets.ModelViewSet):
queryset = Item.objects.all()
serializer_class = CustomSerializer
The CRUD actions are automatically avaliable without needing additional code for each method.
Conclusion
By exploring these classes, we’ve highlighted their differences. Understanding their characteristics allows us to choose the best approach for creating endpoints, balancing project requirements, development speed, and API functionality.
메타데이터
- post_id
- c83fc26e8f7e
- slug
- understanding-apiview-modelviewset-and-viewset-in-django-rest-framework-drf-c83fc26e8f7e
- url
- https://medium.com/@dilibe/understanding-apiview-modelviewset-and-viewset-in-django-rest-framework-drf-c83fc26e8f7e
- canonical_url
- https://medium.com/@dilibe/understanding-apiview-modelviewset-and-viewset-in-django-rest-framework-drf-c83fc26e8f7e
- author_url
- https://medium.com/@dilibe
- status
- ok
- fetched_at
- 2026-07-13 08:05:13