APIView & Function-Based API Views
DRF provides two ways to write views: APIView (class-based) and @api_view (function-based). Both add DRF features like authentication, permissions, content negotiation, and the browsable API on top of standard Django views.
20 min•By Priygop Team•Updated 2026
API Views
- @api_view(['GET', 'POST']) — Function-based API view
- APIView — Class-based API view with get(), post() methods
- Both add: request parsing, response rendering, auth, permissions
- Request — DRF's enhanced request (request.data vs request.POST)
- Response — Returns JSON with proper content type
- status module — HTTP status codes (status.HTTP_200_OK)
API View Examples
API View Examples
# blog/views.py
# from rest_framework.decorators import api_view
# from rest_framework.response import Response
# from rest_framework.views import APIView
# from rest_framework import status
# from .models import Post
# from .serializers import PostSerializer
# Function-based API view
# @api_view(['GET', 'POST'])
# def post_list_api(request):
# if request.method == 'GET':
# posts = Post.objects.filter(published=True)
# serializer = PostSerializer(posts, many=True)
# return Response(serializer.data)
#
# if request.method == 'POST':
# serializer = PostSerializer(data=request.data)
# if serializer.is_valid():
# serializer.save(author=request.user)
# return Response(serializer.data, status=status.HTTP_201_CREATED)
# return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
# Class-based API view
# class PostListAPIView(APIView):
# def get(self, request):
# posts = Post.objects.filter(published=True)
# serializer = PostSerializer(posts, many=True)
# return Response(serializer.data)
#
# def post(self, request):
# serializer = PostSerializer(data=request.data)
# if serializer.is_valid():
# serializer.save(author=request.user)
# return Response(serializer.data, status=status.HTTP_201_CREATED)
# return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
# urls.py
# path('api/posts/', post_list_api),
# path('api/posts/', PostListAPIView.as_view()),Tip
Tip
Use APIView for custom logic and GenericAPIView + mixins for standard CRUD. Choose based on how much customization you need.
Diagram
Loading diagram…
QuerySets are LAZY — no DB hit until evaluated.
Common Mistake
Warning
Not validating request.data. DRF serializers validate automatically, but always check serializer.is_valid(raise_exception=True).
Practice Task
Note
(1) Create an APIView for GET and POST. (2) Handle serialization and validation. (3) Return proper status codes.
Quick Quiz
Key Takeaways
- DRF provides two ways to write views: APIView (class-based) and @api_view (function-based).
- @api_view(['GET', 'POST']) — Function-based API view
- APIView — Class-based API view with get(), post() methods
- Both add: request parsing, response rendering, auth, permissions