Rest framework는 개발자가 state와 API의 interaction을 모델링하는데 더 집중할 수 있도록, 그리고 URL 구조가 공통의 컨션을 기반으로 자동적으로 다뤄지도록 허용해주는 ViewSets
를 다루는 추상화를 포함한다.
ViewSet
클래스는 retrieve
나 update
같은 기능, 그리고 get
이나 put
같은 핸들러 메소드를 제공한다는 점을 제외하고는 View
클래스와 거의 같다고 할 수 있다.
ViewSet
클래스가 뷰의 집합으로 인스턴스화 되었을 때만 오직 마지막 순간에 핸들러 메소드의 집합에만 바운딩 된다. 일반적으로 URL conf를 정의하는데의 복잡함을 다루는 Router
클래스를 사용한다.
ViewSets
를 이용해서 UserList
와 UserDetail
뷰를 단일의 UserViewSet
으로 리팩토링 해줄 수 있다.
from rest_framework import viewsets
class UserViewSet(viewsets.ReadOnlyModelViewSet):
"""
This viewset automatically provides `list` and `retrieve` actions.
"""
queryset = User.objects.all()
serializer_class = UserSerializer
자동적으로 기본 'read-only' 작업을 제공하기위해 ReadOnlyModelViewSet
이 사용되었다. 여전히 queryset
과 serializer_class
속성들을 기존의 view에서 사용한 것처럼 설정한다. 하지만 같은 정보를 더 이상 두 별도의 클래스에 나누어 제공할 필요는 없어진다.
다음 예제에서는 SnippetList
, SnippetDetail
, 그리고 SnippetHighlight
뷰 클래스를 단일의 클래스로 만들어준다.
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework import permissions
class SnippetViewSet(viewsets.ModelViewSet):
"""
This viewset automatically provides `list`, `create`, `retrieve`,
`update` and `destroy` actions.
Additionally we also provide an extra `highlight` action.
"""
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
이번 예제에서는 기본 읽기와 쓰기 작업의 완전한 집합을 얻기위해 ModelViewSet
을 사용하였다.
그리고 highligt
라는 이름의 커스텀 액션을 생성하기 위한 @action
데코레이터도 쓰여졌다. 이 데코레이터는 표준 create
/update
/delete
스타일에 맞지 않는 어떤 커스텀 엔드포인트라도 추가하는데 사용될 수 있다.
@action
데코레이터를 사용하는 커스텀 액션은 기본적으로 GET 요청에 응답하게 된다. 만약 POST
요청에 응답하는 액션을 원한다면 methods
인자를 사용할 수 있다.
기본 커스텀 액션을 위한 URLs는 메소드 이름 자체를 의존한다. 만약 url이 세워지는 방법을 바꾸고 싶다면, url_path
를 데코레이터 키워드 인수로 포함할 수 있다.
핸드럴 메소드는 오직 URLConf를 정의했을때만 액션에 바운딩 된다.