Views & Viewsets 주요 함수 및 활용

DRF ViewSet에서 자주 사용되는 핵심 함수들과 실무 활용법

@action 데코레이터

기본 CRUD 외 커스텀 엔드포인트 추가

  • detail=True/False: 개별 객체/전체 목록 대상 액션 설정

  • methods: 허용할 HTTP 메서드 지정

@action(detail=True, methods=['post'])
def publish_post(self, request, pk=None):
    post = self.get_object()
    post.is_published = True
    post.save()
    return Response(PostSerializer(post).data)

get_serializer_class

요청 종류(action)에 따라 다른 Serializer 동적 반환

def get_serializer_class(self):
    if self.action == 'list':
        return PostSimpleSerializer
    elif self.action == 'create':
        return PostCreateSerializer
    return PostDetailSerializer

get_queryset

동적으로 QuerySet 필터링 및 조작

def get_queryset(self):
    user = self.request.user
    if user.is_staff:
        return Post.objects.all()
    return Post.objects.filter(author=user)

get_object

특정 객체 조회 로직 커스터마이징

def get_object(self):
    obj = super().get_object()
    if not obj.is_published and obj.author != self.request.user:
        raise PermissionDenied()
    return obj

perform_create / perform_update / perform_destroy

객체 생성/수정/삭제 시 추가 로직 실행

def perform_create(self, serializer):
    serializer.save(author=self.request.user)

def perform_update(self, serializer):
    serializer.save(updated_by=self.request.user)

def perform_destroy(self, instance):
    # 소프트 삭제
    instance.is_deleted = True
    instance.save()

get_permissions

HTTP 메서드나 action별로 다른 권한 클래스 적용

def get_permissions(self):
    if self.action in ['list', 'retrieve']:
        return [AllowAny()]
    return [IsAuthenticated()]

lookup_field

pk 대신 slug, uuid 등 다른 필드로 객체 조회

class PostViewSet(viewsets.ModelViewSet):
    lookup_field = 'slug'  # /posts/my-post-slug/ 형태 URL

get_serializer_context

Serializer에 추가 컨텍스트 데이터 전달

def get_serializer_context(self):
    context = super().get_serializer_context()
    context['current_user'] = self.request.user
    return context

filter_queryset

필터링, 검색, 정렬 로직 적용

def filter_queryset(self, queryset):
    queryset = super().filter_queryset(queryset)
    # 추가 필터링 로직
    if self.action == 'list':
        queryset = queryset.select_related('author')
    return queryset

paginate_queryset

커스텀 페이지네이션 로직

def paginate_queryset(self, queryset):
    if self.action == 'list':
        return super().paginate_queryset(queryset)
    return None  # 특정 액션에서는 페이지네이션 비활성화

Last updated