Django(58)viewsets视图集详解
前言
ViewSet 只是一种基于类的视图,它不提供任何方法处理程序(如 .get()或.post()),而是提供诸如.list()和 .create() 之类的操作。
ViewSet 的方法处理程序仅使用 .as_view() 方法绑定到完成视图的相应操作。
通常不是在urlconf中的视图集中显示注册视图,而是要使用路由类注册视图集,该类会自动为你确定 urlconf。
源码分析
我们首先看一下viewsets.py文件的源码结构,如下图

我们可以看到有5个类
- ViewSetMixin
- ViewSet:继承自
ViewSetMixin和APIView - GenericViewSet:继承自
ViewSetMixin和GenericAPIView - ReadOnlyModelViewSet:继承自
RetrieveModelMixin、ListModelMixin、GenericViewSet - ModelViewSet:继承自5大
mixins工具类和GenericViewSet
ViewSetMixin
通过上述代码结构分析,我们了解到只要知道ViewSetMixin是干嘛的,其他的类都继承于它。从源码中我们知道,ViewSetMixin重写了as_view()方法,源码如下:
def as_view(cls, actions=None, **initkwargs):
"""
由于基于类的视图围绕实例化视图创建闭包的方式,我们需要完全重新实现`.as_view`,并稍微修改创建和返回的视图函数。
对于某些路由配置,initkwargs 的名称和描述可能会被明确覆盖,例如,额外操作的名称。
"""
# 名称和描述 initkwargs 可能会被显式覆盖
cls.name = None
cls.description = None
# 后缀 initkwarg 保留用于显示视图集类型。如果提供了名称,则此 initkwarg 应该无效。
cls.suffix = None
cls.detail = None
# 设置 basename 允许视图反转其操作 url。该值由路由器通过 initkwargs 提供。
cls.basename = None
# actions必须不能为空,否则报错
if not actions:
raise TypeError("The `actions` argument must be provided when "
"calling `.as_view()` on a ViewSet. For example "
"`.as_view({'get': 'list'})`")
# 清理关键字参数
for key in initkwargs:
if key in cls.http_method_names:
raise TypeError("You tried to pass in the %s method name as a "
"keyword argument to %s(). Don't do that."
% (key, cls.__name__))
if not hasattr(cls, key):
raise TypeError("%s() received an invalid keyword %r" % (
cls.__name__, key))
# name和suffix是互斥的
if 'name' in initkwargs and 'suffix' in initkwargs:
raise TypeError("%s() received both `name` and `suffix`, which are "
"mutually exclusive arguments." % (cls.__name__))
def view(request, *args, **kwargs):
self = cls(**initkwargs)
if 'get' in actions and 'head' not in actions:
actions['head'] = actions['get']
self.action_map = actions
# 将方法绑定到actions, 这是与标准视图不同的一点
for method, action in actions.items():
handler = getattr(self, action)
setattr(self, method, handler)
self.request = request
self.args = args
self.kwargs = kwargs
return self.dispatch(request, *args, **kwargs)
update_wrapper(view, cls, updated=())
update_wrapper(view, cls.dispatch, assigned=())
view.cls = cls
view.initkwargs = initkwargs
view.actions = actions
return csrf_exempt(view)
从上述源码中了解到,ViewSetMixin重写了as_view方法,as_view是将请求的方法绑定到了actions
ViewSet
class ViewSet(ViewSetMixin, views.APIView):
"""
默认情况下,基本 ViewSet 类不提供任何操作。
"""
pass
ViewSet继承了ViewSetMixin和APIView,增删改查需要我们自己定义
GenericViewSet
class GenericViewSet(ViewSetMixin, generics.GenericAPIView):
"""
GenericViewSet 类默认不提供任何操作,但包含通用视图行为的基本集,例如`get_object` 和`get_queryset` 方法。
"""
pass
GenericViewSet类相比ViewSet,包含了一些视图行为的通用方法
视图集特点
- 视图集都是优先继承
ViewSetMixin类,再继承一个视图类(GenericAPIView或APIView) ViewSetMixin提供了重写的as_view()方法,继承视图集的视图类,配置路由时调用as_view()必须传入 请求-函数名 映射关系字典
eg: path('v1/books/<int:pk>/', views.BookGenericViewSet.as_view({"get": "my_get_obj"}))
GenericAPIView与APIView 作为两大继承视图的区别
GenericViewSet和ViewSet都继承了ViewSetMixin,as_view都可以配置 请求-函数 映射GenericViewSet继承的是GenericAPIView视图类,用来完成标准的model类操作接口ViewSet继承的是APIView视图类,用来完成不需要model类参与,或是非标准的model类操作接口
post请求在标准的model类操作下就是新增接口,登陆的post不满足
post请求验证码接口,不需要model类的参与
案例:登陆的post请求,并不是完成数据的新增,只是用post提交数据,得到的结果也不是登陆的用户信息,而是登陆的认证信息
ReadOnlyModelViewSet
class ReadOnlyModelViewSet(mixins.RetrieveModelMixin,
mixins.ListModelMixin,
GenericViewSet):
"""
提供默认`list()` 和`retrieve()` 操作的视图集。
"""
pass
ModelViewSet
class ModelViewSet(mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
mixins.ListModelMixin,
GenericViewSet):
"""
一个提供默认 `create()`、`retrieve()`、`update()`、`partial_update()`、`destroy()` 和 `list()` 操作的视图集。
"""
pass
实战案例
视图函数如下
class StudentViewSets(viewsets.ModelViewSet):
queryset = Student.objects.all()
serializer_class = StudentModelSerializer
def my_get(self, request, *args, **kwargs):
response = self.retrieve(request, *args, **kwargs)
return APIResponse(results=response.data)
def my_list(self, request, *args, **kwargs):
response = self.list(request, *args, **kwargs)
return APIResponse(results=response.data)
我们继承自ModelViewSet,自带5个mixins工具,我们定义了2个查询方法,然后在urls中配置
urlpatterns = [
path('v2/student/<int:pk>/', views.StudentViewSets.as_view({"get": "my_get"})),
path('v2/student/', views.StudentViewSets.as_view({"get": "my_list"})),
]
在as_view中添加了get请求方式的方法,有pk调用my_get代表单查,没有pk调用my_list代表群查,这样写的原因就是我们的StudentViewSets继承了ViewSetMixin。
Django(58)viewsets视图集详解的更多相关文章
- ThinkPHP视图查询详解
ThinkPHP视图查询详解 参考http://www.jb51.net/article/51674.htm 这篇文章主要介绍了ThinkPHP视图查询,需要的朋友可以参考下 ThinkP ...
- 【转载】D3DXMatrixLookAtLH视图变换函数详解
原文:D3DXMatrixLookAtLH视图变换函数详解 /*D3DXMatrixLookAtLH函数返回的是世界->视图变换矩阵. 视图坐标系和局部坐标系是一样的,都是世界坐标系转换为指定的 ...
- Django 框架篇(四) : 视图(view)详解 以及 路由系统(url)
|--Django的View(视图) |-- CBV和FBV: |-- 给视图增加装饰器: |-- request对象: |-- response对象: |-- Django的路由系统(url): | ...
- Django rest framework (视图类详解)
官网:https://www.django-rest-framework.org/api-guide/viewsets/ 在django rest framework 视图中一共有N个类 第一类:AP ...
- Django之form表单详解
构建一个表单 假设你想在你的网站上创建一个简单的表单,以获得用户的名字.你需要类似这样的模板: <form action="/your-name/" method=" ...
- 068.Python框架Django之DRF视图集使用
一 视图集与路由的使用 使用视图集ViewSet,可以将一系列逻辑相关的动作放到一个类中: list() 提供一组数据 retrieve() 提供单个数据 create() 创建数据 update() ...
- Django路由配置之正则表达式详解
正则表达式详解 urls.py from django.conf.urls import url from . import views urlpatterns = [ url(r'^articles ...
- - > 并查集详解(第二节)
以下是并查集思路详解: 一:概念 并查集处理的是“集合"之间的关系.当给出两个元素的一个无序数对(a,b)时,需要快速“合并”a和b分别所在的集合,这期间需要反复“查找”某元素所在的集合.“ ...
- Django之路由层和视图层详解
路由层 首先我们来看一下,路由层都有哪些东西,其实你看django很人性化,将所有的介绍都放在了简介里面,不信,你看
随机推荐
- hdu1074 状态压缩dp+记录方案
题意: 给你一些作业,每个作业有自己的结束时间和花费时间,如果超过结束时间完成,一天扣一分,问你把n个作业完成最少的扣分,要求输出方案. 思路: 状态压缩dp,记录方案数的地方 ...
- The 2014 ACM-ICPC Asia Mudanjiang Regional First Round A
网选A,水题: 这个是水题,只要枚举一遍,看有多少a[i-1]<a[i]>a[i+1],不解释了.
- Day015 异常处理机制
异常处理机制 抛出异常 捕获异常 异常处理的五个关键字 try:监控一个代码块,有异常就能通过catch捕获 catch(想要捕获的异常类型):捕获想要捕获的异常,catch代码块的代码只有在捕获到异 ...
- Scrum Meeting 4
Basic Info where:共享空间 when:2021/4/29 target: 简要汇报一下已完成任务,下一步计划与遇到的问题 Progress Team Member Position A ...
- 向Vertex Shader传递vertex attribute
在VBO.VAO和EBO那一节,介绍了如何向Vertex Shader传递vertex attribute的基本方法.现在我准备把这个话题再次扩展开. 传递整型数据 之前我们的顶点属性数据都是floa ...
- [网络编程之Socket套接字介绍,套接字工作流程,基于TCP协议的套接字程序]
[网络编程之Socket套接字介绍,套接字工作流程,基于TCP协议的套接字程序] 为何学习socket套接字一定要先学习互联网协议: 1.首先:要想开发一款自己的C/S架构软件,就必须掌握socket ...
- VUE如何关闭代码规范extra semiclon/VUE新手必看-(转载)
VUE如何关闭代码规范 最近在学VUE,作为一个设计转前端的小白鼠. 总是能碰到各种各样奇葩的问题. 比如我碰到了 extra semicolon 百度了下说是这个原因造成的: 但是!!!!!关键点来 ...
- docker 部署应用
Docker 部署应用 所需环境 Linux系统:centos7 (推荐7.4) Docker环境:V1.13.1 镜像:应用镜像包 docker部署和基本命令: 1. docker环境搭建 a) ...
- Java中生成唯一标识符的方法(Day_48)
有时候业务需要生成唯一标识符,但又不能依赖于数据库中自动递增的字段产生唯一ID,比如多表同一字段需要统一一个唯一ID,此时我们就需要用程序来生成一个唯一的全局ID. UUID UUID是指在一台机器上 ...
- 技术干货 | 关于 WKWebview 网络拦截,你想知道的都在这里
原生 WKWebView 在独立于 app 进程之外的进程中执行网络请求,请求数据不经过主进程,因此在 WKWebView 上直接使用 NSURLProtocol 是无法拦截请求的. 但是由于 mPa ...