여기, 서비스 유저가 업로드한 게시글을 조회할 수 있는 두 개의 API뷰가 있습니다.
from rest_framework import generics
from user_community.models import Post
class PostList(generics.ListAPIView):
queryset = Post.postobjects.all()
serializer_class = PostSerializer
class PostDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Post.objects.all()
serializer_class = PostSerializer
각각의 API VIEW에 접근할 수 있는 엔드포인트는 다음과 같습니다.
from django.urls import path
from .views import PostDetail, PostList
urlpatterns = [
path('<int:pk>/', PostDetail.as_view(), name="each_posting_detail"),
path('', PostList.as_view(), name="all_postings_list")
]
두 개의 게시물 조회 API뷰 PostList
와 PostDetail
은 각각 다른 역할을 수행합니다.
ListAPIView
인 PostList
는 전체 게시물을 조회합니다.
RetrieveUpdateDestroyAPIView
인 PostDetail
은 게시물 객체 각각에 대하여 조회, 수정, 삭제 기능을 제공합니다.
게시물을 단순히 조회하도록 하는 것은 문제가 되지 않으나,
수정하거나 삭제하는 것은 권한 제한을 설정할 필요가 있습니다.
게시물의 수정 혹은 삭제 요청을 보낸 사용자가
게시물을 작성한 사용자와 같을 경우에만 수정 및 삭제하도록 만들어주면 좋을 것 같습니다.
저희는 DRF(Django Rest Framework) 커스텀 권한 클래스를 만들어보겠습니다.
완성된 권한 클래스는 다음과 같습니다.
from rest_framework.permissions import BasePermission, SAFE_METHODS
class WritePostingPermission(BasePermission):
message = "해당 게시물의 수정 또는 삭제 권한이 없습니다."
def has_object_permission(self, request, view, obj):
if request.method in SAFE_METHODS:
return True
return obj.author == request.user
모든 DRF custom permission class는 BasePermission
을 상속받아야 합니다.
이후, has_permission
혹은 has_object_permission
메소드를 구현해주어야 합니다.
저의 경우 게시물 객체 각각에 대한 권한을 부여하는 상황이니 후자를 선택하였습니다.
SAFE_METHODS
는 http request중 GET
등의 수정이나 삭제와는 관련이 없는,
단순 조회성 요청의 묶음입니다.
클라이언트 측에서 보낸 요청이 게시물의 수정이나 삭제에 대한 요청이 아닌 경우는,
권한을 True로 부여해주었습니다.
클라이언트의 요청이 DELETE, POST, PATCH, PUT등이라면,
조건문을 빠져나와 아래의 명령어를 수행합니다
return obj.author == request.user
obj는 게시물 객체 각각을 의미하며,
저의 경우 Post 객체의 스키마에 작성자 필드를 author
라는 이름으로 설정해두었습니다.
DB에 저장되어 있는 게시물의 작성자와, request를 보낸 user가 동일하면 True를 리턴해 권한을 부여받습니다.
이제, 이 권한을 API VIEW에 적용해주어야 합니다.
class PostDetail(generics.RetrieveUpdateDestroyAPIView):
permission_classes = [WritePostingPermission]
queryset = Post.objects.all()
serializer_class = PostSerializer
위와 같이, API뷰 내에서, permission_classes = []
속에 권한 클래스를 지정해주면 됩니다.
이제, 해당 API뷰는 RetrieveUpdateDestroyAPIView
임에도, 게시물 작성자 이외에는 Update와 Destroy 기능이 비활성화 됩니다.
[참고자료]
[1] 유튜브 튜토리얼
https://www.youtube.com/watch?v=5AOn0BmSXyE&list=PLOLrQ9Pn6caw0PjVwymNc64NkUNbZlhFw&index=2
[2] DRF 공식문서
https://www.django-rest-framework.org/api-guide/permissions/