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.