get
, post
같은 메소드 핸들러를 제공하지는 않지만, list
, create
같은 액션을 제공한다.이전 DRF의 Auth 부분 코드를 이어 수정하여 테스트할 것이다.
profiles.api.views.py
변경 전
from rest_framework import generics
from rest_framework.permissions import IsAuthenticated
from profiles.models import Profile
from profiles.api.serializers import ProfileSerializer
class ProfileList(generics.ListAPIView):
queryset = Profile.objects.all()
serializer_class = ProfileSerializer
permission_classes = [IsAuthenticated]
변경 후
from rest_framework.viewsets import ReadOnlyModelViewSet
class ProfileViewSet(ReadOnlyModelViewSet):
queryset = Profile.objects.all()
serializer_class = ProfileSerializer
permission_classes = [IsAuthenticated]
profiles.api.urls.py
변경 전
from django.urls import path
from profiles.api.views import ProfileList
urlpatterns = [
path("profiles/", ProfileList.as_view(), name="profile-list")
]
변경 후
from django.urls import path
from profiles.api.views import ProfileViewSet
profile_list = ProfileViewSet.as_view({"get": "list"})
profile_detail = ProfileViewSet.as_view({"get": "retrieve"})
urlpatterns = [
path("profiles/", profile_list, name="profile-list"),
path("profiles/<int:pk>/", profile_detail, name="profile-detail")
]
profiles.api.urls.py
router를 이용하면 경로 지정을 DRF에서 자동화해 주기에 통상 viewset의 url은 router로 설정해준다.
from django.urls import include, path
from rest_framework.routers import DefaultRouter
from profiles.api.views import ProfileViewSet
# router는 자동으로 link들을 생성해낸다.
router = DefaultRouter()
router.register(r"profiles", ProfileViewSet)
urlpatterns = [
path("", include(router.urls))
]
테스트 결과
router.register(r"status", ProfileStatusViewSet, basename="status")
필수 argument
옵션 argument
profiles.api.views.py
from rest_framework import viewsets
from rest_framework import mixins
from profiles.api.permissions import IsOwnProfileOrReadOnly
class ProfileViewSet(mixins.UpdateModelMixin,
mixins.ListModelMixin,
mixins.RetrieveModelMixin,
viewsets.GenericViewSet):
queryset = Profile.objects.all()
serializer_class = ProfileSerializer
permission_classes = [IsAuthenticated, IsOwnProfileOrReadOnly]
profiles.api.permissions.py
from rest_framework import permissions
class IsOwnProfileOrReadOnly(permissions.BasePermission):
def has_object_permission(self, request, view, obj):
if request.method in permissions.SAFE_METHODS:
return True
return obj.user == request.user
결과
profiles.api.views.py
from rest_framework.viewsets import ModelViewSet
from profiles.models import ProfileStatus
from profiles.api.serializers import ProfileStatusSerializer
from profiles.api.permissions import IsOwnerOrReadOnly
class ProfileStatusViewSet(ModelViewSet):
queryset = ProfileStatus.objects.all()
serializer_class = ProfileStatusSerializer
permission_classes = [IsAuthenticated, IsOwnerOrReadOnly]
def perform_create(self, serializer):
user_profile = self.request.user.profile
serializer.save(user_profile=user_profile)
profiles.api.permissions.py
class IsOwnerOrReadOnly(permissions.BasePermission):
def has_object_permission(self, request, view, obj):
if request.method in permissions.SAFE_METHODS:
return True
return obj.user_profile == request.user.profile
profiles.api.urls.py
from profiles.api.views import ProfileViewSet, ProfileStatusViewSet
# 추가
router.register(r"status", ProfileStatusViewSet)
결과
profiles.api.views.py
from profiles.api.serializers import ProfileAvatarSerializer
class AvatarUpdateView(generics.UpdateAPIView):
serializer_class = ProfileAvatarSerializer
permission_classes = [IsAuthenticated]
def get_object(self):
profile_object = self.request.user.profile
return profile_object
profiles.api.urls.py
from profiles.api.views import ..., AvatarUpdateView
urlpatterns = [
...,
path("avatar/", AvatarUpdateView.as_view(), name="avatar-update")
]
결과
참고하면 좋은 사이트