After routing has determined which controller to use for a request, your controller is responsible for making sense of the request and producing the appropriate output.

요청에 어떤 컨트롤러를 사용할지가 결정되면, 컨트롤러는 요청을 이해하게 되고 적절한 출력을 생산한다.

REST framework는 단일 클래스 안에 관련된 뷰의 집합에 대한 로직을 합칠 수 있게 허용해주는데, 그 기능이 바로 Viewset이다. 다른 프레임워크에서도 'Resources'나 'Controllers' 같은 이름으로 불리는 개념적으로 비슷한 기능들을 발견할 수 있다.a

ViewSet 클래스는 .get().post() 같은 어떤 핸들러 메소드도 제공하지 않는 클래스 기반 뷰의 유형이지만, 대신에, .list().create() 같은 액션을 제공한다.

ViewSet의 핸들러 메소드는 .as_view() 메소드를 사용하여 뷰를 마무리하는 순간에 상응하는 액션에만 바인딩 된다.

일반적으로, urlconf 안에 뷰셋 안에 뷰를 명시적으로 등록하는 것 보다는, 보통 뷰셋을 라우터 클래스와 함께 등록하고, 그럼 urlconf를 자동으로 결정해준다.

Example


시스템 안의 유저를 나열하거나 회수할 수 있는 간단한 뷰셋을 정의해보자.

from django.contrib.auth.models import User
from django.shortcuts import get_object_or_404
from myapps.serializers import UserSerializer
from rest_framework import viewsets
from rest_framework.response import Response

class UserViewSet(viewsets.ViewSet):
    """
    A simple ViewSet for listing or retrieving users.
    """
    def list(self, request):
        queryset = User.objects.all()
        serializer = UserSerializer(queryset, many=True)
        return Response(serializer.data)

    def retrieve(self, request, pk=None):
        queryset = User.objects.all()
        user = get_object_or_404(queryset, pk=pk)
        serializer = UserSerializer(user)
        return Response(serializer.data)

필요시, 아래 같이 뷰셋을 개별의 두 뷰로 바인딩 할 수 있다.

user_list = UserViewSet.as_view({'get': 'list'})
user_detail = UserViewSet.as_view({'get': 'retrieve'})

일반적으로, 아래의 방법은 사용하지 않지만, 뷰셋을 라우터와 함께 등록하는 대신, urlconf를 자동적으로 생성되게 할 수도 있다..

from myapp.views import UserViewSet
from rest_framework.routers import DefaultRouter

router = DefaultRouter()
router.register(r'users', UserViewSet, basename='user')
urlpatterns = router.urls

뷰셋을 직접 작성하기보단, 행동의 디폴트 집합을 제공하는 이미 존재하는 기본 베이스 클래스를 더 자주 쓰게 된다.

class UserViewSet(viewsets.ModelViewSet):
    """
    A viewset for viewing and editing user instances.
    """
    serializer_class = UserSerializer
    queryset = User.objects.all()