본문 바로가기
AI/데이터 엔지니어링 데브코스

[3주차-3] 장고를 활용한 API서버 만들기 - Class 기반의 views

by aiant 2023. 4. 29.

Class 기반의 views

 HTTP Method로 view를 만들 때는 분기문을 사용하여 코드를 짰는데, class를 이용하면 분기문(if 문)을 사용할 때보다 코드가 더 간결해진다. 또한 class를 통해 구현하면 장고 rest_framework에서 제공하는 다양한 다른 class들을 활용해서 반복되는 코드를 작성할 필요 없이 쉽게 view를 만들 수 있다(class 상속 받기). 따라서 대부분의 경우에 class를 통해 구현한다고 한다.

polls_api/views.py에서

from rest_framework.views import APIView

class QuestionList(APIView):
    def get(self, request):
        questions = Question.objects.all()
        serializer = QuestionSerializer(questions, many=True)
        return Response(serializer.data)

    def post(self, request):
        serializer = QuestionSerializer(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)

class QuestionDetail(APIView):
    def get(self, request, id):
        question = get_object_or_404(Question, pk=id)
        serializer = QuestionSerializer(question)
        return Response(serializer.data)

    def put(self, request, id):
        question = get_object_or_404(Question, pk=id)
        serializer = QuestionSerializer(question, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_200_OK)
        else:    
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        
    def delete(self, request, id):
        question = get_object_or_404(Question, pk=id)
        question.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

 

 

polls_api/urls.py에서 urlpattern도 함께 바꾸어 줘야 한다.

from django.urls import path
from .views import *


urlpatterns = [
    path('question/', QuestionList.as_view(), name='question-list'),
    path('question/<int:id>/', QuestionDetail.as_view(), name='question-detail'),
]

 



Mixin활용하기

polls_api/views.py에서

from polls.models import Question
from polls_api.serializers import QuestionSerializer
from rest_framework import mixins, generics

class QuestionList(mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView):
    queryset = Question.objects.all()
    serializer_class = QuestionSerializer

    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        return self.create(request, *args, **kwargs)

class QuestionDetail(mixins.RetrieveModelMixin,
                    mixins.UpdateModelMixin,
                    mixins.DestroyModelMixin,
                    generics.GenericAPIView):
    queryset = Question.objects.all()
    serializer_class = QuestionSerializer

    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)


polls_api/urls.py에서 <int:id>를 <int:pk>로 수정

from django.urls import path
from .views import *

urlpatterns = [
    path('question/', QuestionList.as_view(), name='question-list'),
    path('question/<int:pk>/', QuestionDetail.as_view(), name='question-detail'),
]

 



Generic API View 활용하기
Generic API View를 이용하면 매우 간결한 코드로 지금까지 했던 모든 기능을 구현할 수 있다.
이는 generics라는 클래스에 다 구현되어 있기 때문인데, 어떻게 생겼는지 살짝 확인해보면 다음과 같다.

mixin에서 구현했던 코드가 그대로 들어있다.


polls_api/views.py에서

from polls.models import Question
from polls_api.serializers import QuestionSerializer
from rest_framework import generics

class QuestionList(generics.ListCreateAPIView):
    queryset = Question.objects.all()
    serializer_class = QuestionSerializer

class QuestionDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Question.objects.all()
    serializer_class = QuestionSerializer

 

지금까지 배운게 허무해질 정도로 간단하게 구현되었다..