DRF 심화

김주언·2022년 7월 11일
0

Django

목록 보기
7/9
post-thumbnail

DRF의 다양한 뷰

DRF에서 작성하는 뷰는 함수형 뷰와 클래스형 뷰로 구분할 수 있다. 클라이언트 측에서 API 서버로 요청을 보낼 때 URL과 Method를 조합하여 요청을 보내는데, 이 때 같은 URL 내의 여러 Method를 처리하는 방법으로 함수형과 클래스형이 구분되었다.

이 때 URL과 Method의 조합은 보통 5가지 정도 나온다.

  • HTTP GET /books/ : 도서 전체 목록 조회
  • HTTP GET /book/1 : 도서 한권 정보 조회
  • HTTP POST /books/ : 도서 한권 정보 등록
  • HTTP PUT /book/1 : 도서 한권 정보 수정
  • HTTP DELETE /book/1 : 도서 한권 삭제

이러한 조합은 매우 기본적이고 공통적인 기능이기 때문에, 이를 편하고 쉽게 만들기 위한 여러 방법들이 등장했다.


DRF mixins

이전의 booksAPI를 클래스형으로 작성한 코드는 아래와 같다.

class BooksAPI(APIView):
    def get(self, request):
        books = Book.objects.all()
        serializer = BookSerializer(books, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK) 
    def post(self, request):
        serializer = BookSerializer(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 BookAPI(APIView):
    def get(self, request, bid):
        book = get_object_or_404(Book, bid=bid)
        serializer = BookSerializer(book)
        return Response(serializer.data, status=status.HTTP_200_OK)

코드를 살펴보면 하나의 클래스 내부에 중복적인 내용이 많다. 이러한 중복을 제거하기 위해서 DRF는 mixins를 제공한다.

mixins는 APIView에서 request의 method마다 시리얼라이저 코드를 작성하는 것을 줄이기 위해서 클래스 레벨에서 시리얼라이저를 등록한다. 각 method에는 시리얼라이저 코드를 작성하지 않고 method별로 mixin에 연결하여 사용하면 된다.

mixin 사용하여 구현

class BooksAPIMixins(mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer

    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 BookAPIMixins(mixins.RetrieveModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin, generics.GenericAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    lookup_field = 'bid'
    
    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)
    
  • queryset
    모델에 쿼리를 보내서 받아온 결과 데이터를 담아둔다.
  • serializer_class
    해당 API에서 사용할 시리얼라이저를 설정한다.

각 클래스별 메소드의 반환값은 각 메소드별 처리하는 기능에 따라 달라진다.

  • list : HTTP GET /books/
  • create : HTTP GET /book/1 : 도서 한권 정보 조회
  • retrieve : HTTP POST /books/ : 도서 한권 정보 등록
  • update : HTTP PUT /book/1 : 도서 한권 정보 수정
  • destroy : HTTP DELETE /book/1 : 도서 한권 삭제

URLConfig

from django.urls import path, include
from .views import helloAPI, bookAPI, booksAPI, BookAPI, BooksAPI

urlpatterns = [
    path("hello/", helloAPI),
    path("fbv/books/", booksAPI),
    path("fbv/book/<int:bid>/", bookAPI),
    path("cbv/books/", BooksAPI.as_view()),
    path("cbv/book/<int:bid>/", BookAPI.as_view()),
    path("mixin/books/", BooksAPI.as_view()),
    path("mixin/book/<int:bid>/", BookAPI.as_view())

]

DRF generics

DRF mixins 마저 귀찮은 개발자를 위한 제네릭

mixins를 조합해서 미리 만들어둔 mixins 세트이다. 조합의 종류는 아래와 같다

  • generics.ListAPIView : 전체목록 조회
  • generics.CreateAPIView : 생성
  • generics.RetrieveAPIView : 1개 조회
  • generics.UpdateAPIView : 1개 수정
  • generics.DestroyAPIView : 1개 삭제
  • generics.ListCreateAPIView : 전체목록과 생성
  • generics.RetrieveUpdateAPIView : 1개 조회 & 1개 수정
  • generics.RetrieveDestroyAPIView : 1개 조회 & 1개 삭제
  • generics.RetrieveUpdateDestroyAPIView : 1개 조회 & 1개 수정 & 1개 삭제
class BooksAPIGenerics(generics.ListCreateAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer


class BookAPIGenerics(generics.RetrieveUpdateDestroyAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    lookup_field = 'bid'

코드가 많이 짧아졌다!


DRF Viewset과 Router

profile
학생 점심을 좀 차리시길 바랍니다

0개의 댓글