The Django Rest Framework (DRF) is a powerful toolkit that makes it easy to create robust and scalable web APIs with Django. Whether you’re an experienced Django developer or a beginner, having a comprehensive cheat sheet at your disposal can be a game changer. In this article, we’ll go over the most comprehensive Django Rest Framework cheat sheet, which includes key concepts, serializers, views, authentication, and more.
Serializers
Serializers play an important role in converting complex data types, such as Django models, into Python data types that can be easily rendered into JSON, XML, or other content formats. Here’s a quick guide for DRF serializers:
- Define a serializer class by inheriting from
serializers.Serializer
orserializers.ModelSerializer
(for model-based serializers). - Specify fields using class attributes like
CharField
,IntegerField
, etc. - Implement validation logic using methods like
validate_<field_name>()
. - Use serializers to handle both input data validation and output data rendering.
class MyModelSerializer(serializers.ModelSerializer):
class Meta:
model = MyModel
fields = '__all__'
Basic View Types
Views in DRF are analogous to Django’s views, but tailored specifically for handling API requests. They’re responsible for processing incoming requests and returning appropriate responses.
DRF provides different types of views to handle various use cases:
APIView
: The base class for all views. It provides basic request/response handling.ViewSet
: Combines multiple views (list, create, retrieve, update, delete) into a single class.GenericAPIView
: Provides common behavior for CRUD operations.ModelViewSet
: A combination ofGenericAPIView
andViewSet
tailored for model-backed APIs.
HTTP Methods and Corresponding Views
DRF maps HTTP methods to view methods:
GET
:list()
,retrieve()
POST
:create()
PUT
:update()
PATCH
:partial_update()
DELETE
:destroy()
Authentication and Permissions
DRF provides authentication and permission classes to control access to views:
from rest_framework.authentication import BasicAuthentication
from rest_framework.permissions import IsAuthenticated
class MyView(APIView):
authentication_classes = [BasicAuthentication]
permission_classes = [IsAuthenticated]
Custom Permissions
Define custom permissions to control access:
from rest_framework import permissions
class IsOwnerOrReadOnly(permissions.BasePermission):
def has_object_permission(self, request, view, obj):
if request.method in permissions.SAFE_METHODS:
return True
return obj.owner == request.user
ViewSets and Routers
DRF offers ViewSets for a more concise way of defining views:
from rest_framework import viewsets
class MyModelViewSet(viewsets.ModelViewSet):
queryset = MyModel.objects.all()
serializer_class = MyModelSerializer
ViewSets
can be registered with routers
to generate URLs automatically:
from rest_framework.routers import DefaultRouter
router = DefaultRouter()
router.register(r'mymodels', MyModelViewSet)
urlpatterns += router.urls
Pagination
DRF offers built-in pagination classes for handling large data sets:
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 10,
}
Filtering and Ordering
Filter and order querysets using URL query parameters:
class MyModelViewSet(viewsets.ModelViewSet):
queryset = MyModel.objects.all()
serializer_class = MyModelSerializer
filter_backends = [filters.SearchFilter, filters.OrderingFilter]
search_fields = ['name']
ordering_fields = ['name']
API Versioning
You can version your API to avoid breaking changes:
urlpatterns = [
path('v1/', include('myapp.urls')), # Use API versioning in URLs
]
Versioning
Version your APIs using DRF’s versioning classes:
REST_FRAMEWORK = {
'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.NamespaceVersioning',
'ALLOWED_VERSIONS': ['v1', 'v2'],
}
Throttling and Rate Limiting
Protect your API using throttling and rate limiting:
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_CLASSES': [
'rest_framework.throttling.AnonRateThrottle',
'rest_framework.throttling.UserRateThrottle',
],
'DEFAULT_THROTTLE_RATES': {
'anon': '100/day',
'user': '1000/day',
},
}
Content Negotiation
DRF supports content negotiation for handling different media types (JSON, XML, etc.):
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': [
'rest_framework.renderers.JSONRenderer',
'rest_framework.renderers.XMLRenderer',
],
}
Exception Handling
DRF provides built-in exception handling and error responses:
from rest_framework.views import exception_handler
def custom_exception_handler(exc, context):
response = exception_handler(exc, context)
if response is not None:
response.data['custom_message'] = 'An error occurred'
return response
Overriding Generic Views
You can customize the behavior of generic views by overriding methods:
class MyModelListCreateView(generics.ListCreateAPIView):
queryset = MyModel.objects.all()
serializer_class = MyModelSerializer
def perform_create(self, serializer):
serializer.save(user=self.request.user)
View Function Decorators
Use decorators to add behavior to views, such as authentication and permission checks:
from rest_framework.decorators import authentication_classes, permission_classes
@authentication_classes([TokenAuthentication])
@permission_classes([IsAuthenticated])
def my_view(request):
# View logic here
Serializer Context
Pass additional context to serializers:
serializer = MyModelSerializer(instance, context={'request': request})
Rendering Custom Data
Render custom data using Response
and status
:
from rest_framework.response import Response
from rest_framework import status
class MyView(APIView):
def get(self, request):
data = {'message': 'Hello, world!'}
return Response(data, status=status.HTTP_200_OK)
File Uploads
Handle file uploads in views using serializers:
class MyModelSerializer(serializers.ModelSerializer):
class Meta:
model = MyModel
fields = ['file']
class MyModelView(APIView):
def post(self, request):
serializer = MyModelSerializer(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)
Testing Views
DRF provides testing tools to test views and API functionality:
from rest_framework.test import APITestCase
class MyViewTest(APITestCase):
def test_my_view(self):
response = self.client.get('/my-view/')
self.assertEqual(response.status_code, status.HTTP_200_OK)
Serializer Validation
Add custom validation to serializers using validate_<field_name>
methods:
class MySerializer(serializers.ModelSerializer):
def validate_my_field(self, value):
if value < 0:
raise serializers.ValidationError('Value cannot be negative')
return value
DRF with Function-Based Views
You can use DRF features with function-based views:
from rest_framework.decorators import api_view
from rest_framework.response import Response
@api_view(['GET'])
def my_function_view(request):
data = {'message': 'Hello, function view!'}
return Response(data)
Serializing Relationships
Handle related data using serializers:
class AuthorSerializer(serializers.ModelSerializer):
class Meta:
model = Author
fields = ['name', 'books']
class BookSerializer(serializers.ModelSerializer):
author = AuthorSerializer()
class Meta:
model = Book
fields = ['title', 'author']
Combining Views
Combine multiple views into one using ViewSets
and mixins
:
from rest_framework import mixins, viewsets
class MyViewSet(mixins.ListModelMixin,
mixins.RetrieveModelMixin,
viewsets.GenericViewSet):
queryset = MyModel.objects.all()
serializer_class = MyModelSerializer
Caching
Cache responses using DRF’s caching decorators:
from rest_framework.decorators import cache_page
class MyView(APIView):
@cache_page(60 * 15) # Cache for 15 minutes
def get(self, request):
# ...
DRF’s Mixins
Leverage DRF’s mixins for common CRUD operations:
from rest_framework import mixins, viewsets
class MyViewSet(mixins.ListModelMixin,
mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
viewsets.GenericViewSet):
queryset = MyModel.objects.all()
serializer_class = MySerializer
Custom Action
Create custom actions in viewsets:
class MyViewSet(viewsets.ModelViewSet):
@action(detail=True, methods=['post'])
def do_something(self, request, pk=None):
# Custom action logic
Query Parameters
Retrieve query parameters in views:
class MyView(APIView):
def get(self, request):
param_value = request.query_params.get('param_name')
# ...
Custom Nested Relationships
You can use serializer methods to create custom nested relationships:
class AuthorSerializer(serializers.ModelSerializer):
class Meta:
model = Author
fields = '__all__'
class BookSerializer(serializers.ModelSerializer):
author_data = serializers.SerializerMethodField()
class Meta:
model = Book
fields = '__all__'
def get_author_data(self, obj):
author = obj.author
return AuthorSerializer(author, context=self.context).data
Multiple Serializers for a Single View
Use different serializers for different request methods:
class MyModelAPIView(APIView):
serializer_class_read = MyModelReadSerializer
serializer_class_write = MyModelWriteSerializer
def get_serializer_class(self):
if self.request.method in ['GET', 'HEAD']:
return self.serializer_class_read
return self.serializer_class_write
def get(self, request):
# ...
def post(self, request):
# ...
Related Data Creation
Override perform_create
in your view to handle related data creation:
class OrderCreateView(generics.CreateAPIView):
serializer_class = OrderSerializer
def perform_create(self, serializer):
order = serializer.save()
products_data = self.request.data.get('products')
if products_data:
for product_data in products_data:
product = Product.objects.get(id=product_data['id'])
OrderItem.objects.create(order=order, product=product, quantity=product_data['quantity'])
Django Rest Framework offers a variety of tools and features to help you simplify and streamline API development. This cheatsheet provides a comprehensive reference to help you navigate the complexities of DRF views and create efficient and robust APIs for your Django applications.
Recommended Read: Django for APIs
If you’re serious about building APIs with Django, I highly recommend checking out the book [Django for APIs: Build web APIs with Python and Django]

A Note From the Author
Thank you so much for taking the time to read the story. If you found my article helpful and interesting, please share your thoughts in the comment section, and don’t forget to share and clap
Let’s Get in Touch!
- YouTube: mrcoder701
- Instagram: mr_coder_701
- LinkedIn: Gajanan Rajput
- Website: mrcoder701.com
- GitHub: @gajanan0707
- Medium: Gajanan Rajput
Related to authentication and permissions. I have used something similar to this in my viewsets which allow you to use Django default object permissions similar to how the Django admin uses them (it is only really adding the get permissions but is an easy way to restrict an API) Than you can use the default Django permissions with groups to easily control who can use the different endpoint actions this also includes custom viewset actions.
from rest_framework import permissions
from rest_framework.authentication import BasicAuthentication
from rest_framework.permissions import IsAuthenticated
class MyPermissions(permissions.DjangoModelPermissions):
perms_map = {
“GET”: [“%(app_label)s.view_%(model_name)s”],
“OPTIONS”: [],
“HEAD”: [],
“POST”: [“%(app_label)s.add_%(model_name)s”],
“PUT”: [“%(app_label)s.change_%(model_name)s”],
“PATCH”: [“%(app_label)s.change_%(model_name)s”],
“DELETE”: [“%(app_label)s.delete_%(model_name)s”],
}
class MyView(APIView):
authentication_classes = [BasicAuthentication]
permission_classes = [IsAuthenticated | MyPermissions]
Thanks for sharing such a pleasant idea, post is nice, thats why i have
read it entirely
Visit my page :: JSON validator online
I was more than happy to discover this website.
I need to to thank you for your time for this particularly wonderful read!!
I definitely really liked every part of it and i also have you saved as
a favorite to see new information in your site.
my web blog: JSON validator online
great points altogether, you just gained a logo new reader.
What would you suggest about your submit that you made a few days in the past?
Any certain?
Thank you so much, and welcome aboard! I’m glad you enjoyed the points. As for recent posts, let me know if there’s anything specific you’re curious about, and I’d be happy to dive deeper or share extra insights!
Hi there, the whole thing is going fine here and ofcourse every one is sharing
facts, that’s truly good, keep up writing.
I think other website proprietors should take this web site as an model, very clean and great user friendly style and design, let alone the content. You are an expert in this topic!