加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Django REST FrameWork中文教程6: ViewSets&Routers

发布时间:2020-12-15 17:13:00 所属栏目:大数据 来源:网络整理
导读:REST框架包括一个处理的抽象 ViewSets ,它允许开发人员集中精力对API的状态和交互进行建模,并根据常规约定使URL构造自动处理。 ViewSet 类是几乎同样的事情 View 类,但他们提供诸如操作 read ,或者 update ,而不是方法处理,如 get 或 put 。 一个 View

REST框架包括一个处理的抽象ViewSets,它允许开发人员集中精力对API的状态和交互进行建模,并根据常规约定使URL构造自动处理。

ViewSet类是几乎同样的事情View类,但他们提供诸如操作read,或者update,而不是方法处理,如getput

一个ViewSet类在最后一刻被绑定到一组方法处理程序,当它被实例化成一组视图时,通常通过使用一个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。此装饰器可用于添加不适合标准create/?update/?delete样式的任何自定义端点。

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

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

明确地将ViewSets绑定到URL

当我们定义URLConf时,处理程序方法只会被绑定到动作上。看看发生什么事情,让我们首先从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。将资源连接到视图和网址的约定可以使用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'))
]

与路由器注册视图与提供urlpattern类似。我们包括两个参数 - 视图的URL前缀和视图本身。

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

视图vs视图之间的权衡

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

这并不意味着总是采取正确的方法。在使用基于类的视图而不是基于函数的视图时,需要考虑一组类似的权衡。使用viewsets比单独构建视图不太明确。

在本教程的第7部分中,我们将介绍如何添加API模式,并使用客户端库或命令行工具与API进行交互。

Django REST FrameWork中文文档目录:

Django REST FrameWork 中文教程1:序列化

Django REST FrameWork 中文教程2:请求和响应

Django REST FrameWork 中文教程3:基于类的视图

Django REST FrameWork 中文教程4:验证和权限

Django REST FrameWork 中文教程5:关系和超链接API

Django REST FrameWork 中文教程6: ViewSets&Routers

Django REST FrameWork 中文教程7:模式和客户端库


(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读