TIL123. DRF : Mixins, Generics, ViewSets 사용하여 CRUD 구현하기

ID짱재·2022년 2월 16일
0

Django REST Framework

목록 보기
7/10
post-thumbnail

📌 이 포스팅에서는 Django Rest Framework의 Mixins, Generics, ViewSets을 사용하여 더 간결하게 CBV를 구현하는 방법에 대해 정리하였습니다.



🌈 Mixins, Generics, ViewSets 사용하여 CRUD 구현하기

🔥 Mixins를 활용하여 CRUD 구현하기

🔥 Generics를 활용하여 CRUD 구현하기

🔥 ViewSets를 활용하여 CRUD 구현하기



1. Mixins를 활용하여 CRUD 구현하기

✔️ DRF에서 지원하는 mixins는 실제 python에서 제공하는 mixins 문법이 없기 때문에 클래스의 상속 문법을 활용한다.

✔️ 아래 5가지 mixins를 모듈로써 제공한다.

  • CreateModlMixin : post 요청 받았을 때, 생성할 때 create하는 로직
  • ListModelMixin : get 요청 받앗을 때, 목록 조회
  • RetrieveModelMixin : get 요청 받았을 때, 상세 보기 조회
  • UpdateModelMixin : put 또는 patch 요청 받았을 때, 수정
  • DestroyModelMixin : delete 요청 받았을 때, 삭제

✔️ "models.py", "serializers.py", "urls.py"는 기존("FBV로 CRUD 구현하기" 편)과 같기 때문에 생략한다.

✔️ Mixins에서 제공하는 View를 사용하기 위해 rest_framework에서 generics, mixins를 import 해준다.

✔️ Mixins를 상속받아 사용하면, queryset과 serializer_class를 지정하고, 필요 매서드를 작성하면 된다.

✔️ 이에 중복이 사라지고 간결해지는 장점이 있다. 목록은 list, 생성은 post, 상세 보기는 get, 수정은 update, 삭제는 delete 매서드를 이용하여 반환한다.

from rest_framework import generics, mixins # 👈 generics, mixins 가져오기
from fbvApp.models import Student
from fbvApp.serializers import StudentSerializer
# StudentList
class StudentList(mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView):
    queryset = Student.objects.all()
    serializer_class = StudentSerializer
    def get(self, request):
        return self.list(request)
    def post(self, request):
        return self.create(request)
# StudentDetail
class StudentDetail(mixins.RetrieveModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin, generics.GenericAPIView):
    queryset = Student.objects.all()
    serializer_class = StudentSerializer
    def get(self, request, pk):
        return self.retrieve(request, pk)
    def put(self, request, pk):
        return self.update(request, pk)
    def delete(self, request, pk):
        return self.destroy(request, pk)     


2. Generics를 활용하여 CRUD 구현하기

✔️ generic의 ListCreateAPIView, RetrieveUpdateDestoryAPIView를 상속하면 더 간결하게 구현이 가능하다.

✔️ genrics APIView의 종류는 아래와 같다. 다양한 조합으로 사용가능 하다.

  • generics.CreateAPIView : post 요청일 때, create의 매핑되어 object 생성
  • generics.ListAPIView : get 요청일 때, list와 매핑되어 object list 제공
  • generics.RetrieveAPIView : get 요청일 때, retrieve와 매핑되어 object 상세 정보 제공
  • generics.DestroyAPIView : delete 요청일 때, destory와 매핑되어 object 삭제
  • generics.UpdateAPIView : put 요청일 때는 update, patch 요청일 때는 partial_update와 매핑
  • generics.ListCreateAPIView : CreateAPIView와 ListAPIView를 통합
  • generics.RetrieveUpdateAPIView : RetrieveAPIView와 UpdateAPIView를 통합
  • generics.RetrieveDestoryAPIView : RetrieveAPIView와 DestroyAPIView를 통합
  • generics.RetrieveUpdateDestroyAPIView : RetrieveAPIView, UpdateAPIView, DestroyAPIView 통합

✔️ generics에서 제공하는 APIView를 사용하면 아래처럼 더 간결해진다. Mixins에 기능들을 이미 상속받고 있기 때문에 상속받을 generics class 조합으로 간단해졌고, 매서드도 따로 적어줄 필요가 없다.

from rest_framework import generics
from fbvApp.models import Student
from fbvApp.serializers import StudentSerializer
class StudentList(generics.ListCreateAPIView):
    queryset = Student.objects.all()
    serializer_class = StudentSerializer
class StudentDetail(generics.RetrieveUpdateDestroyAPIView):
	queryset = Student.objects.all()
    serializer_class = StudentSerializer


3. ViewSets를 활용하여 CRUD 구현하기

🤔 Viewset 사용하기

✔️ Generics의 코드를 살펴보면, queryset과 serializer_class가 반복되는게 보인다. 두개의 View를 하나로 합친다면 이를 해결할 수 있을 것이다.

✔️ 이를 가능하게해주는 것이 ViewSets이다. 아래코드 몇 줄로 위에 모든 기능이 가능해진다.

✔️ ViewSets를 이용하여 CRUD를 구현하기 위해 rest_framework의 viewsets을 상속받는다.

from rest_framework import viewsets # 👈 viewsets 가져오기
from fbvApp.models import Student
from fbvApp.serializers import StudentSerializer
class StudentViewSet(viewsets.ModelViewSet):
    queryset = Student.objects.all()
    serializer_class = StudentSerializer

🤔 DefaultRoutet 등록하기

✔️ viewsets 이용하기 전, CBV에서는 아래와 같이 urls.py를 작성하여 로직과 경로를 매핑해주었다.

from django.urls import path
from . import views
urlpatterns = [
    path('students/', views.StudentList.as_view()),
    path('students/<int:pk>/', views.StudentDetail.as_view()),
] 

✔️ Viewsets을 이용하면, URL 경로를 잡아주기 위해 router 설정을 해주어야한다.

✔️ 이를 위해 DefaultRouter를 import하고, 등록한 router를 rulpatterns를 통해 include 시켜줘야 한다.

✔️ 왜냐하면, listView 경우 pk가 필요없지만, DetialView의 3개 매서드(GET, PUT, DELETE)의 경우는 pk가 필요하기 때문이다.

from django.urls import path, include
from . import views
from rest_framework.routers import DefaultRouter # 👈 DefaultRouter 가져오기
router = DefaultRouter() # 👈 router 인스턴스 생성
router.register('students', views.StudentViewSet) # 👈 router에 ViewSet 등록
urlpatterns = [
    path('', include(router.urls)) # 👈 router를 include를 통해 경로 매핑
]
profile
Keep Going, Keep Coding!

0개의 댓글