概述

在DRF中,允许在一个类中组合一组相关视图的逻辑,称为ViewSets。比如通过通用视图,可以定义列表视图、详情视图等等,但每个视图位于不同的类中,而通过ViewSets则可以将多个视图放在同一个类中。

ViewSets也是一种基于类的视图,只不过和APIView不同的是,它并不提供如get()、post()等和HTTP请求相对应的方法,而提供的是如list()、create()这样的操作方法。

在配置ViewSets的URL时,一般不会显示进行配置,而是使用Routers类来注册ViewSets,Routers会自动确定URL格式。

Router可以将请求和视图自动进行匹配,并映射相应的处理逻辑。

如果我们使用的是ViewSets而非View,那么我们就没必要自己去配置每个View对应的Url了,直接使用Router注册一个视图集,让Router来完成剩下的工作。

1.viewsets类

使用viewsets时需要导入所在模块:

from rest_framework import viewsets

所有的viewsets类都直接或间接的继承于ViewSetMixin这个基类。目前viewsets相关类有包中有四个类,接下来我们逐一进行总结.

1.1.ViewSet

ViewSets继承了ViewSetMixin和APIView,因此具有APIView的一些属性,如permission_class和authentication_classes属性,但没有实现具体的动作,所以在平时开发时,会很少用到它。该类源码如下:

class ViewSet(ViewSetMixin, views.APIView):
"""
The base ViewSet class does not provide any actions by default.
"""
pass

1.2.GenericViewSet

GenericViewSet继承于ViewSetMixin和GenericAPIView,因此具有GenericAPIView拥有的一些属性和方法,如serializer_class、queryset、get_queryset()、get_object()等其他方法和属性,但同样也没有提供操作请求的动作实现,因此该类经常和其他generic包下的具体通用视图一起使用,如:

class Show(viewsets.GenericViewSet,
generics.ListCreateAPIView):
# ListCreateAPIView将list()和create()方法和get(),post()进行了绑定 serializer_class = SnippetSerializer
queryset = Snippet.objects.all()

该类源码如下:

class GenericViewSet(ViewSetMixin, generics.GenericAPIView):
"""
The GenericViewSet class does not provide any actions by default,
but does include the base set of generic view behavior, such as
the `get_object` and `get_queryset` methods.
"""
pass

1.3.ModelViewSet

该类继承于GenericViewSet,并通过混合各种Mixin类的行为,实现了各种动作的实现。该类源码如下:

class ModelViewSet(mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
mixins.ListModelMixin,
GenericViewSet):
"""
A viewset that provides default `create()`, `retrieve()`, `update()`,
`partial_update()`, `destroy()` and `list()` actions.
"""
pass

因此,通过一个ModelViewSet就可以完成包含列表视图、详情视图等多个视图和请求的操作。

1.4.ReadOnlyModelViewSet

该类继承于GenericViewSet,同时混合了RetrieveModelMixin和ListModelMixin,因此可以用于展示列表视图和详情视图,所以是”只读”的.该类源码如下:

class ReadOnlyModelViewSet(mixins.RetrieveModelMixin,
mixins.ListModelMixin,
GenericViewSet):
"""
A viewset that provides default `list()` and `retrieve()` actions.
"""
pass

对整个viewsets包中的类进行总结之后,下面开始总结下如果通过Router给ViewSets配置URL。

2.Router

在学习ViewSets和Router之前,我们对一个View配置Url是通过如下方式进行的:

urlpatterns = [
path('show/', views.ShowList.as_view()), # 用于列表视图
path('show/<pk>', views.ShowDetail.as_view()) #用于详情视图
]

可以看到,这种方式确实挺麻烦的,针对于不同的View,都需要单独进行配置。

如果是通过ViewSets实现的View,那么通过Router就可以自动配置url了,我们只需给Router注册一个ViewSets,其他的什么都不用管。

使用Router时需要导入所在包:

from rest_framework import routers

如:

from rest_framework.routers import DefaultRouter

router = DefaultRouter()
# 给router注册ShowViewSet
router.register('show', views.ShowViewSet, base_name='show') urlpatterns = [
path('admin/', admin.site.urls),
path('', include(router.urls)),
]

其中,register()方法用来注册一个ViewSets,其所需参数如下:

  • 1.prefix:用于这组路由的URL前缀,该参数必须指定;
  • 2.viewset:ViewSets类,该参数必须指定;
  • 3.base_name:该参数可选,用于指定创建URL的名称,如果未指定,则默认使用viewsets中的queryset属性自动生成,因此,如果viewsets中没有声明queryset属性,则该参数必须设置。

当注册之后,DRF根据具体的viewsets为我们自动生成对个URL,如存在以下viewsets和Router:

# views.py中:

from rest_framework import viewsets

class ShowViewSet(viewsets.ModelViewSet):

    serializer_class = SnippetSerializer
queryset = Snippet.objects.all() # urls.py中:
from rest_framework.routers import DefaultRouter router = DefaultRouter()
router.register('show', views.Show, base_name='show') urlpatterns = router.urls

生成的URL格式如下:

   ^show/$ [name='show-list']
^show/(?P<pk>[^/.]+)/$ [name='show-detail']

目前在routers包中有两个类:SimpleRouter和DefaultRouter,DefaultRouter继承于SimpleRouter,这两个类没有太大区别,只不过DefaultRouter中包含一个其根API视图,它返回包含所有列表视图的超链接。这么说可能不太理解,还是用上面的例子直接对比下两个Router吧:

首先是DefaultRouter来注册一个ViewSets,通过浏览器访问项目根Url:

然后用SimpleRouter试试:

这样一比较,效果一目了然,无需多费口舌。

下面这个表格中记录了URL相关的信息,来自DRF官网:

URL Style HTTP Method Action URL Name
{prefix}/ GET list {basename}-list
POST create
{prefix}/{url_path}/ GET, or as specified by `methods` argument `@action(detail=False)` decorated method {basename}-{url_name}
{prefix}/{lookup}/ GET retrieve {basename}-detail
PUT update
PATCH partial_update
DELETE destroy
{prefix}/{lookup}/{url_path}/ GET, or as specified by `methods` argument `@action(detail=True)` decorated method {basename}-{url_name}

3.总结

虽然使用ViewSets可以将多个视图创建在一个类中,但这是由于这个原因,使用viewsets不如单独构建视图那么明确。因此在设计代码时,因通过具体场景选择是使用generic view呢,还是viewsets呢(不过大多数场景下,我还是选择ViewSets)。

四,ViewSets和Routers的更多相关文章

  1. Django编写RESTful API(六):ViewSets和Routers

    欢迎访问我的个人网站:www.comingnext.cn 前言 在本系列的文章中,我在第一篇和第二篇文章中写的编写Django视图时,使用的都是基于函数的方法,并且每个视图函数之前都会加一个djang ...

  2. django rest framwork教程之 viewsets和routers

    ViewSets 和Routers REST框架包括一个用于抽象处理的ViewSets,允许开发人员集中精力对API的状态和交互进行建模,并根据常见约定自动处理URL构造. Viewset 类和 Vi ...

  3. django drf viewsets和routers

    1.定义VIew from django.shortcuts import render from rest_framework.views import APIView from rest_fram ...

  4. Django REST framework+Vue 打造生鲜超市(四)

    五.商品列表页 5.1.django的view实现商品列表页 (1)goods/view_base.py 在goods文件夹下面新建view_base.py,为了区分django和django res ...

  5. drf框架 - 视图家族 | GenericAPIView | mixins | generics | viewsets

    视图家族 view:视图 generics:工具视图 mixins:视图工具集 viewsets:视图集 学习曲线: APIView => GenericAPIView => mixins ...

  6. drf 教程

    1, 序列化 Serialization 创建一个新环境 在做其他事之前,我们会用virtualenv创建一个新的虚拟环境.这将确保我们的包配置与我们正在工作的其他项目完全隔离. virtualenv ...

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

    从这一点开始,我们将真正开始覆盖REST框架的核心.我们来介绍几个基本的构建块. 请求对象REST框架引入了Request扩展常规的对象HttpRequest,并提供更灵活的请求解析.Request对 ...

  8. Django REST framework 中文教程1:序列化

    建立环境 在我们做任何事情之前,我们将使用virtualenv创建一个新的虚拟环境.这将确保我们的包配置与我们正在开展的任何其他项目保持良好的隔离. virtualenv envsource env/ ...

  9. 从django的序列化到rest-framework 序列化

    1.利用Django的view实现返回json数据 from django.views.generic import View from goods.models import Goods class ...

随机推荐

  1. 在同一个Linux上配置多个git账户

    1.首先在~/.ssh目录下执行 ssh-keygen -t rsa -C "miaoying.new@qq.com" 其中 -C "miaoying.new@qq.co ...

  2. Ubuntu安装MyEclise16 过程差不多

    选择好安装路径,和workpace路径,可能会因为工作空间放的位置不太对,导致myeclipse出现问题. 1.Ubuntu安装MyEclise10 不知道为什么网上会有那么多安装过程,还有配置目录和 ...

  3. EasyuiDatagird绑定分页.NetMVC

    引入EasyUi所有需要的脚本,样式 <link href="/easyui/themes/default/easyui.css" rel="stylesheet& ...

  4. eclipse windowbuilder palette 空白

    今天在 eclipse 上安装了 windowbuilder 插件,但是 palette 一直是空白的,不能放控件. 版本 eclipse 4.9.0, windowbuilder 1.9.0. 经过 ...

  5. The type javax.swing.JComponent cannot be resolved. It is indirectly referenced from required .class files

    一段简单程序, frame.add(lbl);出现 问题. 也不知道为什么就是这里, 而我Ctrl + Shift + T 确实也是没有发现 JComponent . public void disp ...

  6. 监控msyql 连接数 及 各用户连接数

    #!/bin/bash while true do date +%Y%m%d-%H:%M:%S mysql -uroot -p'xxx' -e "select count(1) from i ...

  7. IIS编辑器错误信息:CS0016解决方案

    错误信息: 运行asp.net程序时候,编译器错误消息: CS0016: 未能写入输出文件“c:\Windows\Microsoft.NET\Framework\v2.0.50727\Temporar ...

  8. 35. Oracle监听器启动出错:本地计算机上的OracleOraDb11g_home1TNSListener服务启动后又停止了解决方案

    一.原因分析 你安装oracle的时候是连网的,那么listener.ora文件里的HOST=网络给你分配的IP地址,而在你断网的时候就会出现这样的情况. 三.解决办法 方法一:监听器 通过liste ...

  9. 1. 怎么设置可以使得虚拟机里面既可以访问主机也可以访问局域网而且是静态ip

    方法1: Bridged方式(桥接): (1). 虚拟机网络适配器设置为桥接 (2). 主机设置静态ip (3). 虚拟机也设置静态ip且和宿主机在同一网段 Bridged方式: 在图1中Networ ...

  10. 【ASP.NET 问题】IIS发布网站后出现“检测到在集成的托管管道模式下不适用的ASP.NET设置”的解决办法

    系统环境:win7 asp.net4.0网站挂到本地IIS上报错: google一下,发现N页解决方案,但是点进去一看前篇一律的解决方法是.将IIS7 下网站托管管道由继承模式修改为经典模式,这其实是 ...