Django DRF Cheat Sheet

Django DRF Cheat Sheet

Here's the PDF: Django DRF Cheat Sheet v1.3, and HTML

Welcome. This is a guide to the parts of DRF (Django Rest Framework) that I routinely forget or need to reference periodically. This is not a learning resource nor a tutorial, but intended for those already programming in DRF.
- Charles Thayer

Got constructive feedback? Let me know
(Want a new or different cheat sheet? DRF Basics, Django, CBV, Firebase?)



I've been using Django and DRF off and on for way too long. Lately, I've been working as the CTO of a startup in San Francisco that built a mobile app for "managed messaging" for businesses and professionals. That project incorporated a fair amount of API/Javascript communication, which lead me to take notes on the parts of DRF that I needed to review periodically.

I hope you find it helpful and provide constructive feedback. If enough people do, I'll continue to update and distribute it. Thanks.

-- Charles Thayer (thayer at b2si com)



# Object instance -> Data dict
s = Serializer(instance)

Deserialize (create):

# dict -> Object
s = Serializer(data={..})
instance =


s = Serializer(data={..})
if s.is_valid(raise_exception=False):
  s.errors  # dict(field=[problems..])


s = Serializer(instance, validated_data, partial=True)
new =

Serializer Classes:

class SimpleSerializer(serializers.Serializer):
  name = serializers.CharField(max_length=128)
  user = UserSerializer(required=false)  # nested

def create(self, validated_data):
  kwargs = self.context['view'].kwargs
  return instance

def update(self, instance, validated_data):
  # if self.partial
  return instance

def save(self, **kwargs):
  # instance = super().save(**kwargs)
  nm = self.validated_data.get('name')
  instance =
  return instance

# def validate_(self, name):
def validate_name(self, name):
  if not name:
    raise serializers.ValidationError('Name required')
  return name

def validate(self, data):
  nm = data.get('name')
  if not nm:
    raise serializers.ValidationError({'name': ..})
  return validated_data

class DbSerializer(serializers.ModelSerializer):
  class Meta:
    model = DbModel
    fields = [..]
    list_serializer_class = DbListSerializer
  def to_representation(self, obj) → Dict
  def to_internal(self, data) → Dict # validated



CreateSerializer(data={..}); Object
SerializeSerializer(instance); Dict
UpdateSerializer(instance, data={..}, partial=True)
SetSerializer(instance, data={..})

Serializer Fields:

  • Common: CharField, UUIDField, NullBooleanField, DateTimefield, JSONField, EmailField, ..
  • Special: SerializerMethodField, RelatedField, PrimaryKeyRelatedField, SlugRelatedField, HyperlinkedRelatedField..

Field Args

requiredTrueyesyesraise if missing
allow_nullFalseNone is allowed
default<value>setsIf set, don’t use the arg “required”
sourcethe python form of field access like "" (not double underscore) OR a callable name on the object like get_primary_phone()


  • - dict of (post, put, patch)
  • request.query_param (get)
  • request.user (django.contrib.auth.models.AnonymousUser)
  • request.auth (usually a model instance)
  • HTTP stuff: request.method (e.g. GET), .content_type (e.g. application/json), .META, .headers, .path

view() functions

urlpatterns = [
  path(r'viewfn//', views.my_view_fn),
from django.http import JsonResponse
  def my_view_fn(request, arg1=None):
    if request.method == ‘POST’:
      return JsonResponse({}, status=201)


from rest_framework.test import APIClient, APITestCase

class MyTests(APITestCase):
  def test_basics(self):
    client = APIClient()
    response =
      f'/viewtest/{arg1}', data={..})
    assert response.status_code == 200
    assert response.json().get(‘name’) == name


class SimpleView(APIView):
  def post(self, request, *args, **kwargs):‘name’)
    return Response(..)
  def get(self, request, *args, **kwargs):
  def patch(self, request, *args, **kwargs):
  def delete(self, request, *args, **kwargs):


ViewSets (ModelViewSets)

from rest_framework import permissions

class SimpleViewSet(ViewSet):  # ModelViewSet
  serializer_class = SimpleSerializer
  # queryset = SimpleModel.objects.all()
  lookup_field = 'field'
  authentication_classes = (..,)
  permissions_classes = (permissions.IsAuthenticated,)
  # permissions_classes = (permissions.AllowAny,)
  # filter_backends = (..,)
   def create(self, request, *args, **kwargs):
      return Response(..)

  def update(self, request, *args, **kwargs):
  def partial_update(self, request, *args, **kwargs):
  def destroy(self, request, *args, **kwargs):
  def retrieve(self, request, *args, **kwargs):
  def list(self, request, *args, **kwargs):

  def get_queryset(self):
    # related to self.queryset
    data =
    qp = self.request.query_params
    kwargs = self.kwargs  # args for view

  def get_object(self): → instance
    # see self.lookup_field

  def get_serializer(self):
  def get_serializer_context(self):
    return dict(request=..., view=...

  @detail_router([‘GET’, ‘POST’])
  def custom(request, *args, **kwargs):
from rest_framework.routers import DefaultRouter

router = DefaultRouter()
urlpatterns = [
    path(r‘’, include(router.urls)),