码迷,mamicode.com
首页 > Windows程序 > 详细

API(六)之ViewSets & Routers

时间:2017-05-27 13:32:42      阅读:247      评论:0      收藏:0      [点我收藏+]

标签:trade   ora   www   function   路由器   comm   att   its   format   

REST框架包括一个对ViewSets的抽象处理,它允许开发人员集中精力于modeling the state and interactions of the API, and leave the URL construction to be handled automatically, based on common conventions.

ViewSet类与View类几乎是一样的,除了它们所提供的操作,例如read,或者update,而不是 method handlers,如getput

一个ViewSet类在最后一刻只被绑定到一组 method handlers,当它被实例化成一组视图时,通常使用一个Router类来为你处理定义URL conf的复杂性。

重构使用ViewSets

我们来看看我们目前的视图,并将它们重构成视图集。

首先,让我们把UserListUserDetail视图重构成一个单一的UserViewSet。我们可以删除这两个视图,并用一个类替换它们:

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类来自动提供默认的“只读”操作。我们仍然按照我们使用常规视图的方式设置querysetserializer_class属性,但是我们不再需要向两个不同的类提供相同的信息。

接下来我们要更换SnippetListSnippetDetailSnippetHighlight视图类。我们可以删除三个视图,并再次用一个类替换它们。

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装饰器创建一个名为的自定义操作highlight。此装饰器可用于添加任何异于标准的createupdatedelete样式的自定义端点。

使用@detail_route装饰器的自定义操作默认响应GET请求。如果我们想要一个响应POST请求的动作,我们可以使用methods参数。

默认情况下,自定义操作的URL取决于它本身的方法名。如果要更改URL的构造方式,可以将url_path作为decorator的一个关键字参数。

明确地将ViewSets绑定到URL

当我们定义URLConf时,handler methods 只能绑定到这些操作上。为了看看在底层发生了什么事情,让我们首先从ViewSets开始明确地创建一组视图。

urls.py文件中,我们将ViewSet类绑定到一组具体的视图中。

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‘
})

请注意,我们从每个ViewSet类创建多个视图的方式,通过将http方法绑定到每个视图所需的操作。

现在我们将资源绑定到具体的视图中,我们可以像往常一样使用URL conf注册视图。

urlpatterns = format_suffix_patterns([
    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‘)
])

使用路由器

因为我们使用ViewSet类而不是View类,我们实际上不需要自己设计URL。将资源连接到views和urls的约定可以使用Router自动处理。我们需要做的就是使用a 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‘))
]

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.

我们使用的DefaultRouter类会自动创建API根视图,因此我们现在可以从views模块中删api_root方法。

 

views 与 viewsets之间的权衡

使用viewsets是一个非常有用的抽象。它有助于确保您的API中的URL约定是一致的,最大限度地减少您需要编写的代码量,并允许您专注于API提供的交互和表现层,而不是URL conf的具体内容。

That doesn‘t mean it‘s always the right approach to take. There‘s a similar set of trade-offs to consider as when using class-based views instead of function based views. Using viewsets is less explicit than building your views individually.

 

API(六)之ViewSets & Routers

标签:trade   ora   www   function   路由器   comm   att   its   format   

原文地址:http://www.cnblogs.com/yangxiaoling/p/6912326.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!