[DRF 튜토리얼] 6. ViewSets & Routers

HL·2021년 2월 3일
0

Django

목록 보기
15/15

View 수정

UserList, UserDetail -> UserViewSet
viewset 은 자동으로 list, retrive 기능을 제공

# snippets/views.py
from rest_framework import viewsets

class UserViewSet(viewsets.ReadOnlyModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer

SnippetList, SnippetDetail, SnippetHighlight -> SnippetView

# snippets/views.py
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework import permissions

class SnippetViewSet(viewsets.ModelViewSet):
    queryset = Snippet.objects.all()
    serializer_class = SnippetSerializer
    permission_classes = [permissions.IsAuthenticatedOrReadOnly,
                          IsOwnerOrReadOnly]

    @action(detail=True, renderer_classes=[renderers.StaticHTMLRenderer])
    def highlight(self, request, *args, **kwargs):
        snippet = self.get_object()
        return Response(snippet.highlighted)

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

highlight 함수를 위해 @action 데코레이터를 사용했다
기본 CRUD 가 아닌 custom 을 위해 사용된다
기본적으로 GET method 에 응답한다
POST method 를 사용하려면 methods 인자를 준다
URL 은 기본적으로 함수의 이름이다
바꾸고 싶다면 url_path 를 인자로 준다

URL에 ViewSet 연결하기

# snippets/urls.py
from snippets.views import SnippetViewSet, UserViewSet, api_root
from rest_framework import renderers

snippet_list = SnippetViewSet.as_view({
    'get': 'list',
    'post': 'create'
})
snippet_detail = SnippetViewSet.as_view({
    'get': 'retrieve',
    'put': 'update',
    'patch': 'partial_update',
    'delete': 'destroy'
})
snippet_highlight = SnippetViewSet.as_view({
    'get': 'highlight'
}, renderer_classes=[renderers.StaticHTMLRenderer])
user_list = UserViewSet.as_view({
    'get': 'list'
})
user_detail = UserViewSet.as_view({
    'get': 'retrieve'
})

각 뷰마다 원하는 method 와 action을 연결한다
URL 을 등록한다

# snippets/urls.py
urlpatterns = format_suffix_patterns([
    path('', api_root),
    path('snippets/', snippet_list, name='snippet-list'),
    path('snippets/<int:pk>/', snippet_detail, name='snippet-detail'),
    path('snippets/<int:pk>/highlight/', snippet_highlight, name='snippet-highlight'),
    path('users/', user_list, name='user-list'),
    path('users/<int:pk>/', user_detail, name='user-detail')
])

Router 사용하기

직접 url 을 설정할 필요는 없다
router 을 사용하면 자동으로 가능하다

# snippets/urls.py
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from snippets import views

router = DefaultRouter()
router.register(r'snippets', views.SnippetViewSet)
router.register(r'users', views.UserViewSet)

urlpatterns = [
    path('', include(router.urls)),
]

viewset 을 router 에 등록하는 것은 urlpattern 과 유사하다
두 인자를 넣어준다
DefaultRouter 는 기본적으로 root 를 생성하기 때문에 view 에서 api_root 를 삭제할 수 있다.

View vs ViewSet

ViewSet 이 짧아서 좋지만 항상 좋은 것은 아니다
View 를 사용하는 것이 더 명확해서 유리할 때가 있다

profile
Swift, iOS 앱 개발을 공부하고 있습니다

0개의 댓글