GenericViewSet과 Mixin 조합으로 나만의 CRUD 로직 만들기
GenericViewSet은 기본 구조를 제공하고, Mixin은 개별 CRUD 기능을 담당함. 이 둘을 조합하면 명확하고 안전하며 유연한 맞춤형 ViewSet 제작 가능
ModelViewSet의 한계
보안 문제: 모든 CRUD 기능 노출로 실수로 삭제 기능이 열릴 위험
명확성 부족: ReadOnlyProductViewSet이 ProductViewSet보다 의도가 명확
유연성 부족: 특정 기능만 선택적으로 허용하기 어려움
핵심 개념
GenericViewSet
viewsets.ViewSetMixin과 generics.GenericAPIView를 상속
get_queryset(), get_object(), get_serializer() 등 기반 기능만 제공
실제 액션 메서드(list, create 등)는 포함하지 않음
API의 기본 구조 제공
Mixin 종류
Mixin
액션 메서드
HTTP 메서드
설명
ListModelMixin
list()
GET
목록 조회
CreateModelMixin
create()
POST
객체 생성
RetrieveModelMixin
retrieve()
GET
단일 객체 조회
UpdateModelMixin
update()
PUT, PATCH
객체 수정
DestroyModelMixin
destroy()
DELETE
객체 삭제
조합 패턴
읽기 전용 ViewSet
class ProductReadOnlyViewSet(mixins.ListModelMixin,
mixins.RetrieveModelMixin,
viewsets.GenericViewSet):
queryset = Product.objects.all()
serializer_class = ProductSerializer생성 가능하지만 수정/삭제 불가 ViewSet
class SurveyResponseViewSet(mixins.ListModelMixin,
mixins.RetrieveModelMixin,
mixins.CreateModelMixin,
viewsets.GenericViewSet):
serializer_class = SurveyResponseSerializer
permission_classes = [IsAuthenticated]실무 팁
커스텀 Mixin 생성
class SoftDeleteModelMixin:
def destroy(self, request, *args, **kwargs):
instance = self.get_object()
instance.is_deleted = True
instance.save()
return Response(status=status.HTTP_204_NO_CONTENT)프로젝트 공통 BaseViewSet
class BaseViewSet(viewsets.GenericViewSet):
permission_classes = [IsAuthenticated]
pagination_class = MyCustomPagination주의사항
상속 순서(MRO) 중요: 구체적인 클래스를 왼쪽에, 일반적인 클래스를 오른쪽에 배치
ModelViewSet은 모든 Mixin을 포함한 완전한 CRUD ViewSet
Last updated
