django rest framwork教程之 viewsets和routers


ViewSets 和Routers

REST框架包括一個用於抽象處理的ViewSets,允許開發人員集中精力對API的狀態和交互進行建模,並根據常見約定自動處理URL構造。

Viewset 類和 View類相似,但提供的是read或update, 而不是http動作get或put.一個Viewset 類僅僅可以綁定一組方法處理程序,當它被實例化為一組視圖時,通常通過使用一個處理為您的URL conf的復雜性的路由器類。

使用ViewSets重構

讓我們來看一下我們當前的視圖集,並將它們重構為視圖集。
首先讓我們將UserList和UserDetail重構為UserViewset,然后我們刪除兩個這兩個views,最后使用重構的viewset 替換他們

from rest_framework import viewsets

class UserViewSet(viewsets.ReadOnlyModelViewSet):
    """
    This viewset automatically provides `list` and `detail` actions.
    """
    queryset = User.objects.all()
    serializer_class = UserSerializer

這里我們使用ReadOnlyModelViewSet類來自動提供默認的只讀操作,我們仍然保留queryset和serializer_class屬性,正如我們在使用常規視圖時所做的那樣,但我們不再需要向兩個單獨的類提供相同的信息。
接下來我們將替換snippetList、SnippetDetail和SnippetHighlight

from rest_framework.decorators import detail_route

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,)

    @detail_route(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類來獲得一組完整的默認讀寫操作。注意,我們還使用@detail_route裝飾器創建了一個名為高亮的自定義操作。此裝飾器可用於添加不適合標准創建/更新/刪除樣式的任何自定義端點。
默認情況下,使用@detail_route裝飾器的自定義操作將響應GET請求。如果我們想要一個響應POST請求的操作,我們可以使用methods參數。默認情況下,自定義操作的網址取決於方法名稱本身。如果你想改變URL的構造方式,你可以包含url_path作為裝飾器關鍵字參數。

將viewsets 和urls明確綁定

當我們定義URLConf時,處理程序方法只綁定到動作。要看看發生了什么,我們首先從我們的ViewSets顯式創建一組視圖。
編輯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'
})

請注意我們如何通過將每個視圖的http方法綁定到所需的操作,從每個ViewSet類創建多個視圖

使用routers

我們現在使用的是viewset,相比view,我們不需要定義我們的url,我們使用routers,需要做的是使用路由器注冊適當的視圖集,而其余的資源連接到視圖和網址的約定可以使用Router類自動處理。
修改urls.py

from django.conf.urls import url, include
from snippets import views
from rest_framework.routers import DefaultRouter

# Create a router and register our viewsets with it.
router = DefaultRouter()
router.register(r'snippets', views.SnippetViewSet)
router.register(r'users', views.UserViewSet)

# The API URLs are now determined automatically by the router.
# Additionally, we include the login URLs for the browsable API.
urlpatterns = [
    url(r'^', include(router.urls)),
    url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))
]

向路由器注冊視圖類似於提供url模式。我們包括兩個參數 - 視圖的URL前綴和視圖本身。
我們使用的DefaultRouter類也會為我們自動創建API根視圖,因此我們現在可以從視圖模塊中刪除api_root方法。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM