DRF에서 작성하는 뷰는 함수형 뷰와 클래스형 뷰로 구분할 수 있다. 클라이언트 측에서 API 서버로 요청을 보낼 때 URL과 Method를 조합하여 요청을 보내는데, 이 때 같은 URL 내의 여러 Method를 처리하는 방법으로 함수형과 클래스형이 구분되었다.
이 때 URL과 Method의 조합은 보통 5가지 정도 나온다.
이러한 조합은 매우 기본적이고 공통적인 기능이기 때문에, 이를 편하고 쉽게 만들기 위한 여러 방법들이 등장했다.
이전의 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에 연결하여 사용하면 된다.
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)
각 클래스별 메소드의 반환값은 각 메소드별 처리하는 기능에 따라 달라진다.
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 mixins 마저 귀찮은 개발자를 위한 제네릭
mixins를 조합해서 미리 만들어둔 mixins 세트이다. 조합의 종류는 아래와 같다
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'
코드가 많이 짧아졌다!