Django Rest Framework - My Findings â
đ Cheatsheet â
Views â
api_view
decorator â
py
from django.http import JsonResponse
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework.request import Request
from product.models import Product
from product.serializers import ProductSerializer
@api_view(["GET"])
def index(request: Request):
instance = Product.objects.first() # âšī¸ Your own query
data = ProductSerializer(instance).data if instance else {}
return Response(data)
Generic Views â
py
from rest_framework.generics import RetrieveAPIView, CreateAPIView, ListCreateAPIView, UpdateAPIView, DestroyAPIView
from .models import Product
from .serializers import ProductSerializer
# đ¨ This is create only view. More better approach will be using `ProductListCreateAPIView` as it can list & create on same API endpoint
# urlpatterns: [path("", ProductCreateAPIView.as_view())]
class ProductCreateAPIView(CreateAPIView):
queryset = Product.objects.all()
serializer_class = ProductSerializer
# âšī¸ You can override this method to add custom logic before saving
# Example: Adding the user who created the product or sending a django signal
# def perform_create(self ,serializer: ProductSerializer):
# serializer.save(user=self.request.user)
# # You can also Send django signal
# urlpatterns: [path("<int:pk>/", ProductDetailAPIView.as_view())]
class ProductDetailAPIView(RetrieveAPIView):
queryset = Product.objects.all()
serializer_class = ProductSerializer
# urlpatterns: [path("", ProductListCreateAPIView.as_view())]
class ProductListCreateAPIView(ListCreateAPIView):
queryset = Product.objects.all()
serializer_class = ProductSerializer
# âšī¸ As this is similar to create view, you can also override `perform_create` method
class ProductUpdateAPIView(UpdateAPIView):
queryset = Product.objects.all()
serializer_class = ProductSerializer
# def perform_update(self, serializer: ProductSerializer): ...
class ProductDeleteAPIView(DestroyAPIView):
queryset = Product.objects.all()
serializer_class = ProductSerializer
# def perform_destroy(self, instance: Product): ...
Permissions â
Custom Permission â
py
class IsStaffEditorPermission(permissions.BasePermission):
# Error message when user doesn't have permission
message = "You must be a staff or editor to perform this action."
def has_permission(self, request, view):
user = request.user
# `.has_perm()` is a method provided by Django to check if user has a specific permission
# Format: <app_name>.<verb>_<model_name>
required_permissions = [
"product.add_product",
"product.delete_product",
"product.change_product",
"product.view_product"
]
# TIP: There is also `user.has_perm('product.add_product')` method to check for single permission
if user.is_staff and user.has_perms(required_permissions):
return True
return False