Django rest api Cheatsheet

Ezra Cheatsheet

Django REST API cheatsheet

Essential Note for api design:In a RESTful API, endpoints (URLs) define the structure of the API and how end users access data from our application using the HTTP methods: GET, POST, PUT, DELETE. Endpoints should be logically organized around collections and elements, both of which are resources.

Quickstart

Install:

$ pip install djangorestframework

add to settings.py

INSTALLED_APPS = [
    ...
    'rest_framework',
]

Code Organisation

There are two ways to organize your api code (both of them works) - 1 - either define serializers and routes inside each app (works best for small amount of apps) - 2 - or create api apps such as (api_v1, api_v2) to create all api data in one place (works best for apps with large amount of apps)

Model Object

# This is the model that is used throughout 
# this cehatsheet file, i am keeping it as a reference

class Post(models.Model):
    id = models.AutoField(primary_key=True)
    creation_date = models.DateField(default=timezone.now)
    title = models.CharField(max_length=200)
    content = models.TextField(default="...")

    def __str__(self):
        return "Title: " + self.title

Serialization

# Serializers are used for representing our Model datas in 
# api responses (json, soap .etc) with serializers and deserializers


# appname/serializer.py

from rest_framework import serializers
from profile_app.models import Post


class PostSerializer(serializers.ModelSerializer):
    class Meta:
        model = Post
        fields = '__all__'

Views and Generic Views

# appname/apiviews.py

from rest_framework.views import APIView
from rest_framework.response import Response
from django.shortcuts import get_object_or_404

from profile_app.models import Post
from  .serializers import PostSerializer


class PostList(APIView):
    def get(self, request):
        posts = Post.objects.all()[:20]
        data = PostSerializer(posts, many=True).data
        return Response(data)


class PostDetail(APIView):
    def get(self, request, pk):
        post = get_object_or_404(Post, pk=pk)
        data = PostSerializer(post).data
        return Response(data)

url pathing for the above views

# appname/urls.py

from django.urls import path
from .apiviews import PostList, PostDetail

urlpatterns = [
    path("posts/", PostList.as_view(), name="post_list"),
    path("posts/<int:pk>/", PostDetail.as_view(), name="post_detail")
]

Viewsets and Routers

# if you are using a single serializer in a too
# many views you can just group them into sets

# urls.py
# ...
from rest_framework.routers import DefaultRouter
from .apiviews import PostViewSet


router = DefaultRouter()
router.register('post_set', PostViewSet, basename='post_set')


urlpatterns = [
    # ...
]

urlpatterns += router.urls

# apiviews.py
# ...
from rest_framework import viewsets

from profile_app.models import Post
from  .serializers import PostSerializer

class PostViewSet(viewsets.ModelViewSet):
    queryset = Post.objects.all()
    serializer_class = PostSerializer

We have seen 4 ways to build API views until now - 1 - Pure Django views - 2 - APIView subclasses - 3 - generics.* subclasses - 4 - viewsets.ModelViewSet

So which one should you use when? My rule of thumb is, - Use viewsets.ModelViewSet when you are going to allow all or most of CRUD operations on a model. - Use generics.* when you only want to allow some operations on a model - Use APIView when you want to completely customize the behaviour.

Access Control