목표
이번 tutorial 3에서는 기존 작성했던 함수 형식의 class 기반의 view로 작성해서 더 가독성 있고 코드 길이를 줄이는 것을 배우는 것이 목표입니다.
from snippets.models import Snippet
from snippets.serializers import SnippetSerializer
from django.http import Http404
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
class SnippetList(APIView):
    """
    List all snippets, or create a new snippet.
    """
    def get(self, request, format=None):
        snippets = Snippet.objects.all()
        serializer = SnippetSerializer(snippets, many=True)
        return Response(serializer.data)
    def post(self, request, format=None):
        serializer = SnippetSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
앞서 작성한 함수 기반 view는 이렇게 class 기반 view로 만들 수 있습니다
class SnippetDetail(APIView):
    """
    Retrieve, update or delete a snippet instance.
    """
    def get_object(self, pk):
        try:
            return Snippet.objects.get(pk=pk)
        except Snippet.DoesNotExist:
            raise Http404
    def get(self, request, pk, format=None):
        snippet = self.get_object(pk)
        serializer = SnippetSerializer(snippet)
        return Response(serializer.data)
    def put(self, request, pk, format=None):
        snippet = self.get_object(pk)
        serializer = SnippetSerializer(snippet, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    def delete(self, request, pk, format=None):
        snippet = self.get_object(pk)
        snippet.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)
detail view 또한 이렇게 class 기반으로 코드를 만들 수 있습니다.
그리고 클래스 기반 뷰를 사용하게 되서 urls.py 또한 약간의 리팩토링이 필요합니다
urlpatterns = [
    path('snippets/', views.SnippetList.as_view()),
    path('snippets/<int:pk>/', views.SnippetDetail.as_view()),
#     path('snippets/', views.snippet_list),
#     path('snippets/<int:pk>/', views.snippet_detail),
]
위 두개의 Class들은 앞선 함수 기반 view와 비슷하게 생겨서 차이점이 무엇인지 궁금할 것입니다!
Using mixins
from snippets.models import Snippet
from snippets.serializers import SnippetSerializer
from rest_framework import mixins
from rest_framework import generics
class SnippetList(mixins.ListModelMixin,
                    mixins.CreateModelMixin,
                    generics.GenericAPIView
                  ):
    queryset = Snippet.objects.all()
    serializer_class = SnippetSerializer
    
    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)
    
    def post(self, request, *args, **kwargs):
        return self.create(request, *args, **kwargs)
GenericAPIView, ListModelMixin, CreateModelMixin을 이용해서 view를 구축하고 있습니다.
기본 class도 코어 기능을 제공하고 mixnin class들은 .list(), .create()를 제공합니다 우리는 이것들을 명시적으로(explicitly)
get과 post에 바인딩 해줍니다. 굉장히 간단합니다!
class SnippetDetail(mixins.RetrieveModelMixin,
                    mixins.UpdateModelMixin,
                    mixins.DestroyModelMixin,
                    generics.GenericAPIView):
    queryset = Snippet.objects.all()
    serializer_class = SnippetSerializer
    def get(self, request, *args, **kwargs):
        return self.retrieve(request, *args, **kwargs)
    def put(self, request, *args, **kwargs):
        return self.update(request, *args, **kwargs)
    def delete(self, request, *args, **kwargs):
        return self.destroy(request, *args, **kwargs)
다시 한번 더 GenericAPIView class가 코어 기능을 제공하고 mixins를 통해 .retrieve(), .update() 그리고 .destroy() 기능들을 제공합니다
이렇게 mixin class들을 사용해서 코드들을 약간 덜 사용하도록 작성했지만 여기서 한 단계 더 나아갈 수 있습니다!
Using generic class-based views
REST framework는 이미 generic view와 mixied-in이 되어있는 기능을 제공합니다. 우리는 이것을 이용해서 우리의 view를 다듬을 수 있습니다
from snippets.models import Snippet
from snippets.serializers import SnippetSerializer
from rest_framework import generics
class SnippetList(generics.ListCreateAPIView):
    queryset = Snippet.objects.all()
    serializer_class = SnippetSerializer
class SnippetDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Snippet.objects.all()
    serializer_class = SnippetSerializer
와 이렇게나 코드가 짧아 질 수 있나요
이렇게 저희는 3장 Class-based Views를 배워봤습니다
'Django > restframework' 카테고리의 다른 글
| DRF docs API Guide Responses (0) | 2024.01.12 | 
|---|---|
| DRF docs API Guide Request (0) | 2024.01.09 | 
| DRF tutorial -2 requests and responses (0) | 2024.01.02 | 
| DRF tutorial -1 serialization (0) | 2023.12.28 | 
| django-restframework란 (0) | 2023.12.28 |