django-rst-framework爲咱們提供了ViewSet類, ViewSet爲咱們提供了默認的URL結構, 使得咱們能更專一於API自己. ViewSet類與View類幾乎是相同的, 但提供的是read或update, 而不是http動做get或put.django
ViewSet類在實例化後, 經過Router類, 最終將URL與ViewSet方法綁定. 接下來咱們使用ViewSet代替以前的View.api
將UserList和UserDetail移除, 並替換爲UserViewSet:post
# snippets/views.py
class UserViewSet(viewsets.ReadOnlyModelViewSet): """ 這一viewset提供了`list`和`detail` """ queryset = User.objects.all() serializer_class = UserSerializer
咱們使用ReadOnlyModelViewSet提供默認的只讀權限, queryset和serializer_class設置仍是未變.測試
將SnippetList, SnippetDetail和SnippetHighlight移除, 替換爲SnippetViewSet:url
# snippets/views.py
from rest_framework.decorators import link class SnippetViewSet(viewsets.ModelViewSet): """ 這一viewset提供了`list`, `create`, `retrieve`, `update` 和 `destroy` 但咱們須要本身設置 `highlight`. """ queryset = Snippet.objects.all() serializer_class = SnippetSerializer permission_classes = (permissions.IsAuthenticatedOrReadOnly, IsOwnerOrReadOnly,) @link(renderer_classes=[renderers.StaticHTMLRenderer]) def highlight(self, request, *args, **kwargs): snippet = self.get_object() return Response(snippet.highlighted) def pre_save(self, obj): obj.owner = self.request.user
咱們使用ModelViewSet類實現讀寫操做API. 咱們使用了@link修飾器來建立自定義的highlight動做, 這一修飾器能夠用於建立非標準路徑. @link修飾器對應的是get request, 若是想對應post request, 可使用@action修飾器.spa
爲了更清楚ViewSet內部發生的事情, 咱們首先在urls.py中使用明確指明的關聯:rest
# snippets/urls.py
from snippets.views import SnippetViewSet, UserViewSet 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' }) urlpatterns = format_suffix_patterns(patterns('snippets.views', url(r'^$', 'api_root'), url(r'^snippets/$', snippet_list, name='snippet-list'), url(r'^snippets/(?P<pk>[0-9]+)/$', snippet_detail, name='snippet-detail'), url(r'^snippets/(?P<pk>[0-9]+)/highlight/$', snippet_highlight, name='snippet-highlight'), url(r'^users/$', user_list, name='user-list'), url(r'^users/(?P<pk>[0-9]+)/$', user_detail, name='user-detail') ))
Router類能夠輕鬆的幫咱們實現URL和ViewSet之間的關聯, 咱們先註釋掉snippets/urls.py中全部內容, 而後從新改寫tutorial/urls.py:orm
# tutorial/urls.py
from django.conf.urls import patterns, url, include from snippets import views from rest_framework.routers import DefaultRouter # 黃建router並註冊viewset. router = DefaultRouter() router.register(r'snippets', views.SnippetViewSet) router.register(r'users', views.UserViewSet) # router會自動生成url # 咱們只須要額外提供可瀏覽性登入API urlpatterns = patterns('', url(r'^', include(router.urls)), url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')) )
使用ViewSet類爲咱們提供了統一的URL地址, 減小了代碼的量, 是咱們更專一於API自己.router
但這不表明必定要使用ViewSet類, ViewSet相對於View更爲不明確. 因此在使用中須要特別注意blog
接下來可使用以前的方式測試咱們的API了.
原文連接: http://www.weiguda.com/blog/24/