객체 레벨 권한(Object-level Permission) 직접 만들기
DRF에서 특정 객체에 대한 세밀한 권한 제어를 위해 커스텀 권한 클래스를 직접 구현하는 방법

객체 레벨 권한이 필요한 이유
사용자는 자신이 작성한 게시글만 수정/삭제 가능
관리자는 자신이 담당하는 상품 정보만 변경 가능
팀원은 자신이 속한 프로젝트의 이슈만 조회 가능
IsAdminUser나IsAuthenticated같은 전역 권한으로는 세밀한 제어 불가능
DRF 권한 검사 흐름
has_permission: View에 대한 전역적 접근 권한 검사 (객체 조회 전)has_object_permission: 특정 객체에 대한 접근 권한 검사 (객체 조회 후)has_object_permission은 List API에서는 호출되지 않음 (Detail API에서만 호출)
IsOwnerOrReadOnly 권한 클래스 구현
모델 정의
class Post(models.Model):
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
title = models.CharField(max_length=100)
content = models.TextField()커스텀 권한 클래스
from rest_framework import permissions
class IsOwnerOrReadOnly(permissions.BasePermission):
def has_object_permission(self, request, view, obj):
# 읽기 권한은 모두에게 허용
if request.method in permissions.SAFE_METHODS:
return True
# 쓰기 권한은 소유자만 허용
return obj.author == request.userViewSet에 적용
class PostViewSet(viewsets.ModelViewSet):
queryset = Post.objects.all()
serializer_class = PostSerializer
permission_classes = [IsAuthenticatedOrReadOnly, IsOwnerOrReadOnly]실무 팁
관리자 예외 처리
def has_object_permission(self, request, view, obj):
if request.method in permissions.SAFE_METHODS:
return True
if request.user.is_staff:
return True
return obj.author == request.userList 뷰 필터링
def get_queryset(self):
user = self.request.user
if user.is_staff:
return Post.objects.all()
return Post.objects.filter(author=user)N+1 쿼리 방지
queryset = Post.objects.select_related('author').all()범용 소유권 확인
def has_object_permission(self, request, view, obj):
if request.method in permissions.SAFE_METHODS:
return True
if hasattr(obj, 'author'):
return obj.author == request.user
if hasattr(obj, 'user'):
return obj.user == request.user
return FalsePreviousSimple JWT: Access Token, Refresh Token 기본 설정과 활용법NextDjango DRF: 외부 서비스를 위한 API Key 인증 방식 구현
Last updated
