LOADING

Follow me

Django REST framework(官方教程-六)
十一月 27, 2013|IT

Django REST framework(官方教程-六)



教程 6: ViewSets & Routers


REST 框架包含对于ViewSets的抽象处理,其允许开发者专注于API模块状态与交互,基于约定,使得URL自动处理。


ViewSet 跟 View 相仿,
除了提供的read与update操作以外,它没有get与put操作。


ViewSet  只在最后绑定一组方法处理程序, 当实例化一组 views, 特别实在使用Router ,其可以处理 复杂的URL导向适合的配置。


用 ViewSets重构


让我们定义当前的视图,并重构viewset


首先 让我们把 UserList 和 UserDetail 视图合并到 UserViewSet中.
移除这2个视图, 用一单一class替代它:

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 class,其自动提供默认的
 ‘read-only’ 操作. We’re still setting the
queryset and serializer_class attributes
exactly as we did when we were using regular views, but we no longer need to provide the same information to two separate classes.


之后我们移除 SnippetListSnippetDetail 和 SnippetHighlight视图类.
我们溢出这3个视图并合并到一个class中。

from rest_framework.decorators import link

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

    @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 以取得 完备的读写操作.


Notice 我们也使用 @link 装饰器 以定义一方法 highlight.
这个装饰器能被用于任何不适合create/update/delete方法的自定义结点.


使用@lin装饰器以响应GET请求. 如果需要响应POST请求,我们同样可以使用 @action装饰器 .


将ViewSets 与 URLs 进行绑定


只有当我们定义URLConf时,处理程序的方法才绑定到操作上。我们首先明确ViewSets创建一组视图。

urls.py 文件中我们绑定把 ViewSet 绑定到
具体视图中.

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


Using Routers


重写 urls.py 文件.

from django.conf.urls import patterns, 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 browseable API.
urlpatterns = patterns('',
    url(r'^', include(router.urls)),
    url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))
)


Registering the viewsets with the router is similar to providing a urlpattern. We include two arguments – the URL prefix for the views, and the viewset itself.


The DefaultRouter class we’re using also automatically
creates the API root view for us, so we can now delete the api_rootmethod
from our views module.




no comments
Share

发表评论