Tutorial on How to Implement A Django Rest API ViewSet - bounswe/bounswe2024group11 GitHub Wiki

Two Paradigms

  • APIView
  • Viewset (ModelViewSet etc)

APIView:

  • You implement every endpoint from scratch. Example:
from rest_framework.views import APIView
from rest_framework.response import Response

class MyView(APIView):
    def get(self, request):
        # Handle GET request
        return Response({'message': 'Hello, world!'})

ViewSet

  • Provides default implementations for common CRUD operations, which can be customized by overriding specific methods. Example:
  • Needs a serializer for actions (actions are defined below, CRUD-like). The actions act on this defined serializer
  • ModelViewSet is a viewset that provides default create(), retrieve(), update(), partial_update(), destroy() and list() actions. You can overwrite them. For different actions, you can define different permissions.
    # overwrite an action
    def list(self, request):
        queryset = User.objects.all()
        serializer = UserSerializer(queryset, many=True)
        return Response(serializer.data)
    # self is a viewset object. set a specific permission
    if self.action == 'list':
        permission_classes = [IsAuthenticated]
  • You can create an action that does not inherit any default implementation.
    # a new action
    @action(detail=False, methods=['GET'], name='Get comments')
    def list_comments(self, request, *args, **kwargs):
        queryset = Post.objects.filter(in_reply_to_post = self.kwargs["pk"])
        serializer = self.get_serializer(queryset)
        return Response(serializer.data)
  • You have to register your viewset in the URL
from myapp.views import UserViewSet
from rest_framework.routers import DefaultRouter

router = DefaultRouter()
router.register(r'users', UserViewSet, basename='user')
urlpatterns = router.urls
from rest_framework.viewsets import ModelViewSet
from myapp.models import MyModel
from myapp.serializers import MyModelSerializer

class MyModelViewSet(ModelViewSet):
    queryset = MyModel.objects.all()
    serializer_class = MyModelSerializer