API Views
- Create REST API endpoints using DRF APIView and function-based views.
What are API Views?
API Views are special Django views provided by DRF that handle API requests and return JSON responses.
Can be function-based or class-based
Allow GET, POST, PUT, PATCH, DELETE
Integrate easily with Serializers
Function-Based APIs (FBV)
Function-Based View (FBV) in DRF
Use @api_view decorator
Explicitly define HTTP methods
Simple FBV GET API
views.py
from rest_framework.decorators import api_view
from rest_framework.response import Response
@api_view(['GET'])
def hello_api(request):
return Response({"message": "Hello from FBV API"})
Description
@api_view(['GET']) → Only GET requests allowed
Response → returns JSON automatically
FBV CRUD Example
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework import status
from .models import Student
from .serializers import StudentModelSerializer
@api_view(['GET', 'POST'])
def student_list(request):
if request.method == 'GET':
students = Student.objects.all()
serializer = StudentModelSerializer(students, many=True)
return Response(serializer.data)
elif request.method == 'POST':
serializer = StudentModelSerializer(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)
Description
GET → Fetch all students
POST → Create new student
status → Use HTTP status codes
Advantages of Function-Based API
Simple & easy for beginners
Explicit & clear for small projects
Quick for learning
Limitations
Code repetition in CRUD operations
Hard to scale for large projects
No built-in class utilities
Class-Based APIs (CBV)
What is a Class-Based APIView?
CBV uses APIView class from DRF
Provides built-in structure for GET, POST, PUT, DELETE
Cleaner & reusable for large APIs
Simple CBV API
views.py
from rest_framework.views import APIView
from rest_framework.response import Response
class HelloAPI(APIView):
def get(self, request):
return Response({"message": "Hello from CBV API"})
Description
APIView → base class
Define methods: get(), post(), put(), delete()
Cleaner than FBV for multiple endpoints
CBV CRUD Example
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from .models import Student
from .serializers import StudentModelSerializer
class StudentListAPI(APIView):
def get(self, request):
students = Student.objects.all()
serializer = StudentModelSerializer(students, many=True)
return Response(serializer.data)
def post(self, request):
serializer = StudentModelSerializer(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)
CBV Detail API (Single Object)
class StudentDetailAPI(APIView):
def get_object(self, pk):
try:
return Student.objects.get(pk=pk)
except Student.DoesNotExist:
return None
def get(self, request, pk):
student = self.get_object(pk)
if student is None:
return Response({"error": "Not Found"}, status=status.HTTP_404_NOT_FOUND)
serializer = StudentModelSerializer(student)
return Response(serializer.data)
def put(self, request, pk):
student = self.get_object(pk)
if student is None:
return Response({"error": "Not Found"}, status=status.HTTP_404_NOT_FOUND)
serializer = StudentModelSerializer(student, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def delete(self, request, pk):
student = self.get_object(pk)
if student is None:
return Response({"error": "Not Found"}, status=status.HTTP_404_NOT_FOUND)
student.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
Description
Handles GET, PUT, DELETE for single object
get_object() → DRY approach
Returns proper HTTP status codes
FBV vs CBV
Decorators in CBV
Apply @api_view equivalent
from django.utils.decorators import method_decorator
from rest_framework.decorators import api_view
from rest_framework.views import APIView
@method_decorator(api_view(['GET']), name='dispatch')
class MyAPI(APIView):
def get(self, request):
return Response({"message": "Hello"})