[블로그 만들기 #3-1] - DRF의 ViewSet 완벽 이해하기

2025. 12. 15. 11:52📚 Django

[블로그 3-1] ViewSet 완벽 이해하기

📦 ViewSet 완벽 이해하기

Django REST Framework의 ViewSet 개념부터 활용까지


DRF ViewSet REST API

🤔 ViewSet이란?

ViewSet은 Django REST Framework에서 제공하는 강력한 도구로, 관련된 여러 개의 API 뷰를 하나의 클래스로 묶어서 관리할 수 있게 해줍니다.

쉽게 말해, CRUD(생성, 조회, 수정, 삭제) 작업을 위한 여러 함수를 한 곳에 모아놓은 컨테이너라고 생각하면 됩니다.

일반 View vs ViewSet

구분 일반 View ViewSet
코드량 많음 (각 기능마다 별도 클래스) 적음 (하나의 클래스)
URL 설정 수동으로 각각 연결 Router가 자동 생성
사용 난이도 중간 쉬움
추천 상황 커스터마이징이 많이 필요할 때 표준 CRUD가 필요할 때

📚 ViewSet의 종류

1️⃣ ViewSet (기본)

가장 기본적인 ViewSet으로, 아무 기능도 제공하지 않습니다. 모든 메서드를 직접 구현해야 합니다.

사용 예: 특수한 커스텀 로직이 필요할 때
2️⃣ GenericViewSet

ViewSet + GenericAPIView의 조합입니다. queryset과 serializer_class 같은 속성을 제공하지만, 실제 액션 메서드는 제공하지 않습니다.

사용 예: Mixin과 조합해서 필요한 기능만 선택적으로 구현
3️⃣ ReadOnlyModelViewSet

읽기 전용 ViewSet입니다. 목록 조회(list)와 상세 조회(retrieve)만 가능합니다.

제공 액션: list(), retrieve()
4️⃣ ModelViewSet ⭐ (가장 많이 사용)

완전한 CRUD 기능을 제공하는 ViewSet입니다. 생성, 조회, 수정, 삭제 모두 가능합니다.

제공 액션: list(), create(), retrieve(), update(), partial_update(), destroy()

⭐ ModelViewSet 상세 분석

가장 많이 사용되는 ModelViewSet이 제공하는 6가지 액션을 자세히 알아봅시다.

🎯 ModelViewSet이 자동으로 제공하는 액션
액션 HTTP 메서드 URL 패턴 설명
list() GET /posts/ 전체 목록 조회
create() POST /posts/ 새 객체 생성
retrieve() GET /posts/1/ 특정 객체 조회
update() PUT /posts/1/ 전체 필드 수정
partial_update() PATCH /posts/1/ 일부 필드만 수정
destroy() DELETE /posts/1/ 객체 삭제

기본 사용 예제

views.py
from rest_framework import viewsets
from .models import Post
from .serializers import PostSerializer


class PostViewSet(viewsets.ModelViewSet):
    """
    이 두 줄만으로 6가지 액션이 모두 생성됩니다!
    - list: GET /posts/
    - create: POST /posts/
    - retrieve: GET /posts/1/
    - update: PUT /posts/1/
    - partial_update: PATCH /posts/1/
    - destroy: DELETE /posts/1/
    """
    queryset = Post.objects.all()
    serializer_class = PostSerializer
✅ 단 2줄로 완성!

ModelViewSet을 사용하면 querysetserializer_class 두 줄만 작성해도 완전한 CRUD API가 만들어집니다!

🎨 ViewSet 커스터마이징

1. 특정 액션 오버라이드하기

views.py
class PostViewSet(viewsets.ModelViewSet):
    queryset = Post.objects.all()
    serializer_class = PostSerializer
    
    def list(self, request):
        """목록 조회를 커스터마이징"""
        # 최근 10개만 가져오기
        queryset = Post.objects.all()[:10]
        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)

2. 커스텀 액션 추가하기

views.py
from rest_framework.decorators import action
from rest_framework.response import Response


class PostViewSet(viewsets.ModelViewSet):
    queryset = Post.objects.all()
    serializer_class = PostSerializer
    
    # 커스텀 액션: GET /posts/recent/
    @action(detail=False, methods=['get'])
    def recent(self, request):
        """최근 게시글 5개 반환"""
        recent_posts = Post.objects.all()[:5]
        serializer = self.get_serializer(recent_posts, many=True)
        return Response(serializer.data)
    
    # 커스텀 액션: POST /posts/1/publish/
    @action(detail=True, methods=['post'])
    def publish(self, request, pk=None):
        """특정 게시글 발행"""
        post = self.get_object()
        post.is_published = True
        post.save()
        return Response({'status': 'published'})
🔍 @action 데코레이터 설명
  • detail=False - 전체 목록에 대한 액션 (예: /posts/recent/)
  • detail=True - 특정 객체에 대한 액션 (예: /posts/1/publish/)
  • methods=['get'] - 허용할 HTTP 메서드 지정

3. queryset 동적 필터링

views.py
class PostViewSet(viewsets.ModelViewSet):
    serializer_class = PostSerializer
    
    def get_queryset(self):
        """사용자별 맞춤 queryset 반환"""
        queryset = Post.objects.all()
        
        # URL 파라미터로 필터링
        # 예: /posts/?category=tech
        category = self.request.query_params.get('category')
        if category:
            queryset = queryset.filter(category=category)
        
        return queryset

✨ ViewSet의 장점

🚀 빠른 개발

단 몇 줄의 코드로 완전한 CRUD API를 구현할 수 있어 개발 속도가 매우 빠릅니다.

📦 코드 재사용

관련된 로직을 하나의 클래스로 묶어 코드 중복을 줄이고 유지보수가 쉽습니다.

🔗 Router와 조합

Router와 함께 사용하면 URL 패턴을 자동으로 생성해주어 편리합니다.

🎨 확장성

기본 기능 외에 커스텀 액션을 쉽게 추가할 수 있어 확장성이 뛰어납니다.

📝 일관성

표준화된 구조로 팀원 간 코드 이해와 협업이 용이합니다.

🛡️ 안정성

DRF에서 검증된 코드를 사용하므로 버그가 적고 안정적입니다.

📌 정리

ViewSet 핵심 요약
  • ViewSet은 관련된 여러 API 뷰를 하나로 묶는 컨테이너입니다
  • ModelViewSet이 가장 많이 사용되며, 완전한 CRUD를 자동 제공합니다
  • 단 2줄(queryset, serializer_class)로 API 완성
  • @action 데코레이터로 커스텀 액션 추가 가능
  • Router와 함께 사용하면 URL을 자동 생성

감사합니다.

Make code better! 🚀