Python/DRF

[DRF] DB에 저장된 데이터를 APIview와 ViewSet으로 Response하기

emhaki 2023. 2. 17. 11:17
728x90
반응형
SMALL

 

Django REST Framework에서 views.py 파일은 API 엔드포인트를 처리하는 함수를 정의하는 곳이다. 기본적으로 DRF에서 제공하는 APIview나 ViewSet 클래스를 상속하여 사용하며, 각 클래스는 HTTP 요청 메서드(GET, POST, PUT, DELETE)에 대한 처리 함수를 가지고 있다.

 

DB에 저장된 데이터를 출력하는 방법을 살펴보기전에 views.py의 기본적인 구조는 다음과 같다.

🔎 views.py

from rest_framework.views import APIView
from rest_framework.response import Response

class MyView(APIView):
    def get(self, request):
        # GET 요청 처리
        # 결과 데이터 처리

        return Response('응답 결과')

    def post(self, request):
        # POST 요청 처리
        # 결과 데이터 처리

        return Response('응답 결과')

위 코드에서 MyView클래스는 APIView 클래스를 상속하고, HTTP GET 요청에 대한 처리 함수인 get 메서드와 HTTP POST 요청에 대한 처리 함수인 post 메서드를 가지고 있다. 각 메서드에서는 request 객체를 인자로 받고, 처리 결과를 DRF의 Response 객체로 반환한다.

 

하지만 APIView 클래스는 HTTP 요청 메서드를 직접 처리하기 때문에 요청에 따라 여러 개의 처리 함수를 작성해야 할 때는 중복 코드가 많아질 수 있다. 이 때에는 ViewSet 클래스를 사용하면 간단하게 처리할 수 있다.

🔎 views.py

from rest_framework.viewsets import ModelViewSet
from .models import News
from .serializers import NewsSerializer

class NewsViewSet(ModelViewSet):
    queryset = News.objects.all()
    serializer_class = NewsSerializer

위 코드에서 NewsViewSet 클래스는 ModelViewSet 클래스를 상속하고, queryset과 serializer_class 속성을 정의한다. queryset 속성은 해당 VIewSet에서 사용할 쿼리셋을 정의하며 serializer_class 속성은 해당 ViewSet에서 사용할 Serializer클래스를 정의한다.

 

여기서 DRF의 장점이 나오는데 ModelViewSet 클래스는 앞서 언급했던 APIView 클래스를 상속하면서 queryset과 serializer_class속성을 사용하여 자동으로 CRUD API를 제공한다. 이 때 serializer_class는 해당 모델을 JSON 등으로 직렬화하거나 역직렬화하는 역할을 한다. ModelViewSet 클래스에서는 CRUD API외에도 추가적인 API 엔드포인트를 정의할 수 있다.

 

만약 DB에 저장된 데이터를 인자로 받아 다른 모델의 데이터를 출력하고 싶다면 다음과 같이 코드를 작성할 수 있을 것이다.

🔎 views.py

from rest_framework.viewsets import ModelViewSet
from rest_framework.response import Response
from .models import News
from .serializers import NewsSerializer

class NewsViewSet(ModelViewSet):
    queryset = News.objects.all()
    serializer_class = NewsSerializer

    def list(self, request, *args, **kwargs):
        game_date = request.query_params.get('game_date')
        queryset = self.filter_queryset(self.get_queryset())

        if game_date is not None:
            queryset = queryset.filter(game_date=game_date)

        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)

위 코드에서 list 메서드는 HTTP GET 요청에 대한 처리 함수이다. query_params를 사용하여 GET 파라미터를 가져올 수 있다. game_date 파라미터가 있다면, 해당 일자에 해당하는 News모델 데이터만 가져와서 직렬화를 한다. 그리고 Response 객체로 직렬화한 데이터를 반환한다.

 

위와 같이 ModelViewSet 클래스를 사용하면 CRUD API를 자동으로 만들어주기 때문에 API 엔드포인트를 정의하는데 유용하다. APIView 클래스와 ViewSet 클래스를 상황에 따라 적절히 사용하면 깔끔한 코드를 작성할 수 있다.

728x90
반응형