作者:HelloGitHub-追梦人物[1]

文中所涉及的示例代码,已同步更新到 HelloGitHub-Team 仓库[2]

在 RESTful 架构中,对资源的常规操作无非就是查询、新增、修改、删除等这么几种。为此,django-rest-framework 分别提供了对应通用类视图函数。但是,如果对同一个资源的不同操作逻辑分散在各个视图函数中,从逻辑上来说不太合理,实际中管理起来也不是很方便,还会产生很多重复性的代码。因此,django-rest-framework 引入了视图集(Viewsets),把对同一个资源的不同操作,集中到一个类中。同样的,针对 Web 开发中的常见逻辑,django-rest-framework 也提供了通用视图集,进一步简化开发工作。

使用视图集的一个更大的好处,就是可以配合 django-rest-framework 提供的路由器(router),自动生成 API 的 URL,不需要我们再手工将 URL 模式和视图函数绑定了。所以大部分情况下,即使对资源只有一种操作,我们一般也会使用视图集。

先来看看博客首页文章列表视图集的代码:

blog/views.pyfrom rest_framework import viewsets
from rest_framework import mixinsclass PostViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):serializer_class = PostListSerializerqueryset = Post.objects.all()pagination_class = PageNumberPaginationpermission_classes = [AllowAny]

所有视图集都要继承视图集的基类。视图集也有 2 个基类:ViewSetGenericViewSet,前者是最基本的视图集类,后者拓展自前者,拓展了很多 Web 开发中的通用逻辑。

要注意一点的是,视图集基类提供的是除资源操作以外的通用逻辑(例如 HTTP 请求预处理、HTTP 响应后处理、认证、鉴权等),而对于资源的操作(如序列化、更新、删除资源等)则放在相应的 Mixin 混入类里。django-rest-framework 提供了资源操作的 5 个混入类,分别对应资源的创建、查询、更新、删除。

  • CreateModelMixin

    提供 create 方法用于创建资源

  • ListModelMixin 和 RetrieveModelMixin

    提供 list 和 retrieve,分别用于获取资源列表和单个资源

  • UpdateModelMixin

    提供 update 方法用于更新资源

  • DestroyModelMixin

    提供 destroy 方法用于删除资源

此外,create、list、retrieve、update、destroy 的方法名会被映射为对应的 action,称为对资源操作的一个动作。前面说到视图集的一个最大好处就是可以使用路由器(router)自动生成 URL 模式。URL 正是根据 action 的类型来生成的,后面我们会具体说到。

好了,视图集已经创建完毕,接下来我们从视图集生成视图函数,并绑定 URL。

blog/views.pyindex = PostViewSet.as_view({'get': 'list'})
blog/urls.pyapp_name = "blog"
urlpatterns = [# ...# path("api/index/", views.IndexPostListAPIView.as_view()),path("api/index/", index),
]

等等,不是说视图集的一个好处是使用路由器自动生成 URL 模式吗?为什么还要手工创建视图函数,然后绑定 URL?

别急,这里只是演示一下如何从视图集生成视图函数并绑定 URL,这样能够帮助你更好地理解视图集的工作方式。事实上,使用路由器自动生成 URL 模式时,路由器内部就是采用了和上面手工生成视图函数并绑定 URL 一样的方式。

路由器的使用非常简单,我们在 初始化 RESTful API 风格的博客系统 中引入了 DefaultRouter 以开启 API 交互后台,DefaultRouter 实例化时默认帮我们注册了一个 API 交互后台的根视图,现在要注册一个新的视图,调用其 register 方法就可以了:

blogproject/urls.pyfrom blog.views import PostViewSet
from rest_framework.routers import DefaultRouterrouter = DefaultRouter()
router.register(r'posts', PostViewSet, basename='post')

Django-rest-framework 提供 SimpleRouterDefaultRouter 两个路由器类,后者是对前者的拓展,因此通常情况下都使用后者。DefaultRouter 增加了一个 api 的根路由,访问根路由的 URL 就可以看到其他注册的全部 api 路由,一会儿我们将会看到具体的效果。

视图集自动生成 URL 模式非常简单,只需实例化一个路由器,然后调用其 register 方法,这个方法接收 3 个参数,第一个参数是 URL 前缀,所有从注册的视图集生成的 URL 都会带有这个前缀。第二个参数就是视图集,第三个参数 basename 用于指定视图集生成的视图函数名的前缀。在 django 的 URL 中,一条路由通常由 URL 模式,对应的视图函数和视图函数名组成。视图函数名的作用主要用于解析视图函数所对应的 URL。视图集最终会被转为多个视图函数,那么这个视图函数的名字是什么呢?django-rest-framework 的默认生成规则是 basename-action。

例如这里 basename='post',列出资源列表的 action 为 list(见上一篇教程中关于 action 的讲解),所以生成的获取文章资源列表的视图函数名为 post-list,使用 reverse('post-list') 就可以解析出获取文章资源列表的 API(URL)。

basename 可以不指定,django-rest-framework 会自动从视图集 get_queryset 方法返回的结果所关联的 model 获取一个默认值,其值为 model 名小写。不过,根据 Python 之禅,显式优于隐式,因此即使你设置的 basename 和 django-rest-framework 默认生成的一样,也比不指定要好。

刚才说了,我们使用 DefaultRouter 这个路由器,它会自动帮我们注册一个根路由,来看看根路由下有什么。

运行开发服务器,访问 http://127.0.0.1:8000/api/,界面如下:

django-rest-framework 为我们自动生成了 API 交互后台,在这个界面中可以和我们创建的 API 交互,非常方便。API 交互后台首页是所有注册的视图集对应的 URL。目前只有一条 /api/posts/,点击超链接进去,可以看到 /api/posts/ 的返回结果,即全部文章列表。

但是,目前我们的 api 一股脑将全部文章列表的返回了。但是我们的博客文章列表是有分页功能的,接下来我们就使用 django-rest-framework 提供的分页辅助类,一行代码就可以完成分页功能。

参考资料

[1]HelloGitHub-追梦人物: https://www.zmrenwu.com

[2]HelloGitHub-Team 仓库:https://github.com/HelloGitHub-Team/HelloDjango-REST-framework-tutorial

关注公众号加入交流群

『讲解开源项目系列』——让对开源项目感兴趣的人不再畏惧、让开源项目的发起者不再孤单。跟着我们的文章,你会发现编程的乐趣、使用和发现参与开源项目如此简单。欢迎联系我(微信:xueweihan,备注:讲解)加入我们,让更多人爱上开源、贡献开源~

往期回顾:

第 4 篇:用类视图实现首页 API

第 3 篇:实现博客首页文章列表 API

第 2 篇:初始化 RESTful API 风格的博客系统

第 5 篇:用视图集,简化你的代码相关推荐

  1. Drf从入门到精通五(2个视图基类、5个视图拓展类、9个视图子类、视图集)

    文章目录 一.2个视图基类 1) 基于AIPView写5个接口 2) 基于GenericAPIView写5个接口 二.5个视图拓展类 1) 基于GenericAPIView+5个视图拓展类写接口 三. ...

  2. RESTful之视图集ViewSet

    使用视图集ViewSet,可以将一系列逻辑相关的动作放到一个类中: list() 提供一组数据 retrieve() 提供单个数据 create() 创建数据 update() 保存数据 destor ...

  3. django之视图集

    1.普通视图集 定义视图时需要指明action(行为.动作) 2.模型视图集 # 写分类的视图--模型视图集 class FruitCates(viewsets.ModelViewSet):# 指明操 ...

  4. Django DRF 视图集

    文章目录 1. ViewSet 2. GenericViewSet 3. ModelViewSet 4. ReadOnlyModelViewSet 5. ViewSetMixin 源码分析 6. 视图 ...

  5. drf之day05: 2个视图基类,GenericAPIView的属性和方法,基于APIView写5个接口,基于GenericAPIView写5个接口,5个视图扩展类,9个视图子类,视图集

    目录标题 一:2个视图基类 1.GenericAPIView的属性和方法 二:基于APIView写5个接口 三:基于GenericAPIView写5个接口 四:五个视图扩展类 1..基于Generic ...

  6. 视图集ViewSet

    2019独角兽企业重金招聘Python工程师标准>>> 使用视图集ViewSet,可以将一系列逻辑相关的动作放到一个类中: list() 提供一组数据 retrieve() 提供单个 ...

  7. 游戏开发优化篇之合并图集

    对于性能来说,很多情况都是用空间换时间. 然后在尽量减少空间的占用,在两者之间做抉择. 首先我们了解一下性能指标 帧率:每秒游戏循环执行的次数,即每秒多少帧 越高越好 drawcall: 一帧中游戏调 ...

  8. 不得了不得了,这款开源类库可以帮你简化每一行代码,服了服了

    "黑铁时代"读者群里有个小伙伴感慨说,"Hutool 这款开源类库太厉害了,基本上该有该的工具类,它里面都有."讲真的,我平常工作中也经常用 Hutool,它确 ...

  9. gin context和官方context_Go Web 小技巧(一)简化Gin接口代码

    不知道大家在使用 Gin 构建 API 服务时有没有这样的问题: 参数绑定的环节可不可以自动处理? 错误可不可以直接返回,不想写空 return, 漏写就是 bug 本文通过简单地封装,利用 go 的 ...

最新文章

  1. red hat 6 安装php,Red hat linux服务器简明安装手册(OpenSSL+Mysql+Apache2+PHP)
  2. safari使用canvas引入域外的图片
  3. 企业职工能实行弹性退休吗?
  4. shell命令locate
  5. 建立SAP Router后,开放SAP访问的步骤
  6. pandas表字段为空用其余表替换
  7. 旧文重现,10种职场经典寓言
  8. 笔记四:onsubmit和onclick的区别
  9. BP神经网络公式推导
  10. 微信小程序上传头像,使用wx.chooseImage; wx.uploadFile
  11. 《电路》邱关源 思维导图 第四章-电路定理
  12. 微信小程序开发工具编辑样式文件后模拟器不显示
  13. 提个醒。阿里内网最新发布“M8”级Java面试笔记,助力金三银四
  14. 基于微信小程序的校园食堂窗口自助点餐系统#毕业设计
  15. R计算两列数据的相关系数_Python+pandas计算数据相关系数(person、Kendall、spearman)...
  16. 现有的人脸数据库介绍及下载链接
  17. 数据库查询显示一年中所有的周一到周五的数据
  18. 代理模式和Spring的AOP(持续更新)
  19. 【梅哥的Ring0湿润插入教程】第一课Windows内核/驱动编程概述及应用、商业驱动保护软件原理分析...
  20. 计算机三级网络技术大题内容,全国计算机三级网络技术大题技巧资料.doc

热门文章

  1. mysql bad gateway_502 Bad Gateway
  2. 【C语言】strcpy()函数
  3. 【Google CodeReview 代码评审之道】如何处理审阅人的评论
  4. android 从新浪微博获取用户信息,Android授权登录新浪微博获取用户个人信息
  5. [激光器原理与应用-6]:Q开关元件与Q驱动电路板
  6. Metasploit训练营中,Zingiri Web Shop插件漏洞分析
  7. 【极客大挑战 2019】Havefun
  8. 三星.android beam,功能进化 实测三星S Beam与NFC不同之处
  9. Unity shader 水波 ,模拟雨滴落的水波
  10. css3如何写下拉菜单,css如何实现下拉菜单 超详细