在路由已經(jīng)確定了用于請求的控制器之后,你的控制器負(fù)責(zé)理解請求并產(chǎn)生適當(dāng)?shù)妮敵??!?nbsp;Ruby on Rails 文檔
Django REST framework允許你將一組相關(guān)視圖的邏輯組合在單個類(稱為 ViewSet)中。 在其他框架中,你也可以找到概念上類似于 'Resources' 或 'Controllers'的類似實(shí)現(xiàn)。
ViewSet 只是一種基于類的視圖,它不提供任何方法處理程序(如 .get()或.post()),而是提供諸如 .list() 和 .create() 之類的操作。
ViewSet 的方法處理程序僅使用 .as_view() 方法綁定到完成視圖的相應(yīng)操作。
通常不是在 urlconf 中的視圖集中顯示注冊視圖,而是要使用路由類注冊視圖集,該類會自動為你確定 urlconf。
讓我們定義一個簡單的視圖集,可以用來列出或檢索系統(tǒng)中的所有用戶。
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)
如果我們需要,我們可以將這個viewset綁定到兩個單獨(dú)的視圖,想這樣:
user_list = UserViewSet.as_view({'get': 'list'})
user_detail = UserViewSet.as_view({'get': 'retrieve'})
通常我們不會這么做,我們會用一個router來注冊我們的viewset,讓urlconf自動生成。
from myapp.views import UserViewSet
from rest_framework.routers import DefaultRouter
router = DefaultRouter()
router.register(r'users', UserViewSet)
urlpatterns = router.urls
不需要編寫自己的視圖集,你通常會想要使用提供默認(rèn)行為的現(xiàn)有基類。例如:
class UserViewSet(viewsets.ModelViewSet):
"""
用于查看和編輯用戶實(shí)例的視圖集。
"""
serializer_class = UserSerializer
queryset = User.objects.all()
與使用 View 類相比,使用 ViewSet 類有兩個主要優(yōu)點(diǎn)。
這兩者都有一個權(quán)衡。使用常規(guī)的 views 和 URL confs 更明確也能夠?yàn)槟闾峁└嗟目刂啤iewSets有助于快速啟動和運(yùn)行,或者當(dāng)你有大型的API,并且希望在整個過程中執(zhí)行一致的 URL 配置。
REST framework 中包含的默任 routes 將為標(biāo)準(zhǔn)的 create/retrieve/update/destroy 類型操作提供路由, 如下所示:
class UserViewSet(viewsets.ViewSet):
"""
示例 viewset 演示了將由路由器類處理的標(biāo)準(zhǔn)動作。
如果你使用格式后綴,請務(wù)必為每個動作包含一個`format=None` 的關(guān)鍵字參數(shù)。
"""
def list(self, request):
pass
def create(self, request):
pass
def retrieve(self, request, pk=None):
pass
def update(self, request, pk=None):
pass
def partial_update(self, request, pk=None):
pass
def destroy(self, request, pk=None):
pass
如果你有需要被路由到的特別方法,你可以使用 @detail_route 或 @list_route 裝飾器將它們標(biāo)記為需要路由。
@detail_route 裝飾器在其URL模式中包含 pk 用于需要單個實(shí)例的方法。The @list_route 裝飾器用于對對象列表進(jìn)行操作的方法。
例如:
from django.contrib.auth.models import User
from rest_framework import status
from rest_framework import viewsets
from rest_framework.decorators import detail_route, list_route
from rest_framework.response import Response
from myapp.serializers import UserSerializer, PasswordSerializer
class UserViewSet(viewsets.ModelViewSet):
"""
一個提供標(biāo)準(zhǔn)動作的 viewset
"""
queryset = User.objects.all()
serializer_class = UserSerializer
@detail_route(methods=['post'])
def set_password(self, request, pk=None):
user = self.get_object()
serializer = PasswordSerializer(data=request.data)
if serializer.is_valid():
user.set_password(serializer.data['password'])
user.save()
return Response({'status': 'password set'})
else:
return Response(serializer.errors,
status=status.HTTP_400_BAD_REQUEST)
@list_route()
def recent_users(self, request):
recent_users = User.objects.all().order('-last_login')
page = self.paginate_queryset(recent_users)
if page is not None:
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)
serializer = self.get_serializer(recent_users, many=True)
return Response(serializer.data)
裝飾器可以另外獲取為路由視圖設(shè)置的額外參數(shù)。例如...
@detail_route(methods=['post'], permission_classes=[IsAdminOrIsSelf])
def set_password(self, request, pk=None):
...
這些裝飾器將默認(rèn)路由 GET 請求,但也可以通過使用 methods 參數(shù)接受其他 HTTP 方法。例如:
@detail_route(methods=['post', 'delete'])
def unset_password(self, request, pk=None):
...
這兩個新動作將在 urls ^users/{pk}/set_password/$ 和 ^users/{pk}/unset_password/$上可用。
更多建議: