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 PostDetailSerializerget_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 objperform_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/ 형태 URLget_serializer_context
Serializer에 추가 컨텍스트 데이터 전달
def get_serializer_context(self):
context = super().get_serializer_context()
context['current_user'] = self.request.user
return contextfilter_queryset
필터링, 검색, 정렬 로직 적용
def filter_queryset(self, queryset):
queryset = super().filter_queryset(queryset)
# 추가 필터링 로직
if self.action == 'list':
queryset = queryset.select_related('author')
return querysetpaginate_queryset
커스텀 페이지네이션 로직
def paginate_queryset(self, queryset):
if self.action == 'list':
return super().paginate_queryset(queryset)
return None # 특정 액션에서는 페이지네이션 비활성화Last updated
