목표
이번 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 |