CBV源码与APIView源码解析
一、CBV源码解析
在我们写cbv的时候在url中和fbv的区别就是是否调用了as_view()方法,所以关键入手点就是这个方法
@classonlymethod
# 这是类的绑定方法,这个cls是我们创造的类
def as_view(cls, **initkwargs):
def view(request, *args, **kwargs):
# self是在实例化一个对象
self = cls(**initkwargs)
if hasattr(self, 'get') and not hasattr(self, 'head'):
self.head = self.get
self.request = request
self.args = args
self.kwargs = kwargs
# 关键在dispatch内
return self.dispatch(request, *args, **kwargs)
return view
def dispatch(self, request, *args, **kwargs):
# http_method_names是一个存放了所有请求方式的列表
if request.method.lower() in self.http_method_names:
# 用到了反射的方法吗,如果CBV中我们写了这个请求的方法,就把他赋值给handler,如果没有就返回一个not_allowed
handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
else:
handler = self.http_method_not_allowed
return handler(request, *args, **kwargs)
二、APIView源码解析
apiview同样关键点在as_view中
@classmethod
def as_view(cls, **initkwargs):、
# 继承了父类View的as_view的调用结果,就是父类的view
view = super().as_view(**initkwargs)
view.cls = cls
view.initkwargs = initkwargs
# 这是调用了屏蔽csrf检测的装饰器
return csrf_exempt(view)
# 这里要注意区分,return中的view,其实就是父类中的view
def view(request, *args, **kwargs):
# 关键还是在dispatch内
# 注意此刻dispatch的查找顺序,定义的类中没有,去父类APIView中找,我们发现了新的dispatch方法
return self.dispatch(request, *args, **kwargs)
# APIView的dispatch方法
def dispatch(self, request, *args, **kwargs):
self.args = args
self.kwargs = kwargs
# 重新包装成一个request对象,以后再用的request对象,就是新的request对象了
request = self.initialize_request(request, *args, **kwargs)
self.request = request
self.headers = self.default_response_headers # deprecate?
try:
# 三大认证模块,在下面展示
self.initial(request, *args, **kwargs)
# Get the appropriate handler method
# 这里和父类一样就是调用请求函数的
if request.method.lower() in self.http_method_names:
handler = getattr(self, request.method.lower(),
self.http_method_not_allowed)
else:
handler = self.http_method_not_allowed
# 响应模块,调用请求函数得到一个响应对象,此时内部存放的是json数据
response = handler(request, *args, **kwargs)
except Exception as exc:
# 异常模块
response = self.handle_exception(exc)
# 渲染模块,我们能在前端看到api的html页面,就是这里做的
self.response = self.finalize_response(request, response, *args, **kwargs)
return self.response
# APIView的initial方法,认证模块
def initial(self, request, *args, **kwargs):
# 认证组件:校验用户 - 游客、合法用户、非法用户
# 游客:代表校验通过,直接进入下一步校验(权限校验)
# 合法用户:代表校验通过,将用户存储在request.user中,再进入下一步校验(权限校验)
# 非法用户:代表校验失败,抛出异常,返回403权限异常结果
self.perform_authentication(request)
# 权限组件:校验用户权限 - 必须登录、所有用户、登录读写游客只读、自定义用户角色
# 认证通过:可以进入下一步校验(频率认证)
# 认证失败:抛出异常,返回403权限异常结果
self.check_permissions(request)
# 频率组件:限制视图接口被访问的频率次数 - 限制的条件(IP、id、唯一键)、频率周期时间(s、m、h)、频率的次数(3/s)
# 没有达到限次:正常访问接口
# 达到限次:限制时间内不能访问,限制时间达到后,可以重新访问
self.check_throttles(request)
# 我们再看看新赋值的request内部是什么
def initialize_request(self, request, *args, **kwargs):
"""
Returns the initial request object.
"""
parser_context = self.get_parser_context(request)
return Request(
request,
parsers=self.get_parsers(),
authenticators=self.get_authenticators(),
negotiator=self.get_content_negotiator(),
parser_context=parser_context
)
# 再点击Request,我们发现原来的request被封装给_request了,之后使用request都是在原来基础上新造的
# 原来的request都是.属性的,所以我们可以很肯定这里重写了点拦截方法(__getattr__)
def __getattr__(self, attr):
try:
return getattr(self._request, attr) #通过反射,取原生的request对象,取出属性或方法
except AttributeError:
return self.__getattribute__(attr)
APIView还给我们做了一件事情,因为我们后面在通过api进行数据交互的时候用的都是json格式的数据,但是django默认不会处理json格式的数据,所以这里他新定义的request有一个data方法
@property
def data(self):
if not _hasattr(self, '_full_data'):
self._load_data_and_files()
return self._full_data
他还重新定义了GET的名字,我们本来拿到get请求来的数据应该是django.GET来的,但是由于我们是查找数据,这样的名字不够见名知意所以,
@property
def query_params(self):
"""
More semantically correct name for request.GET.
"""
return self._request.GET
用request.query_params来替代request.GET,当然由于之前重写request的时候用了反射的方法把原生request的方法属性全都赋值给了新的request所以GET也是能用的
CBV源码与APIView源码解析的更多相关文章
- CBV源码分析+APIVIew源码分析
{drf,resful,apiview,序列化组件,视图组件,认证组件,权限组件,频率组件,解析器,分页器,响应器,URL控制器,版本控制} 一.CBV源码分析准备工作: 新建一个Django项目 写 ...
- Restful规范-APIView源码分析
目录 一.Restful规范 十条规范 二.drf的简单使用 三.APIView源码分析 CBV源码分析 APIView源码分析 一.Restful规范 Restful规范是一种web API接口的设 ...
- DRF之APIView源码解析
目录 Django项目中的代码如下 APIView源码解析 源码解析总结 Django项目中的代码如下 urls.py中: from django.conf.urls import url from ...
- $Django cbv源码分析 djangorestframework框架之APIView源码分析
1 CBV的源码分析 #视图 class login (View): pass #路由 url(r'^books/$', views.login.as_view()) #阅读源码: #左侧工程栏--- ...
- DRF cbv源码分析 restful规范10条 drf:APIView的源码 Request的源码 postman的安装和使用
CBV 执行流程 路由配置:url(r'^test/',views.Test.as_view()), --> 根据路由匹配,一旦成功,会执行后面函数(request) --> 本质就是执 ...
- DRF(1) - REST、DRF(View源码解读、APIView源码解读)
一.REST 1.什么是编程? 数据结构和算法的结合. 2.什么是REST? 首先回顾我们曾经做过的图书管理系统,我们是这样设计url的,如下: /books/ /get_all_books/ 访问所 ...
- REST、DRF(View源码解读、APIView源码解读)
一 . REST 前言 1 . 编程 : 数据结构和算法的结合 .小程序如简单的计算器,我们输入初始数据,经过计算,得到最终的数据,这个过程中,初始数据和结果数据都是数据,而计算 ...
- Restful 1 -- REST、DRF(View源码解读、APIView源码解读)及框架实现
一.REST 1.什么是编程? 数据结构和算法的结合 2.什么是REST? - url用来唯一定位资源,http请求方式来区分用户行为 首先回顾我们曾经做过的图书管理系统,我们是这样设计url的,如下 ...
- Django rest framework框架——APIview源码分析
一.什么是rest REST其实是一种组织Web服务的架构,而并不是我们想象的那样是实现Web服务的一种新的技术,更没有要求一定要使用HTTP.其目标是为了创建具有良好扩展性的分布式系统. 可用一句话 ...
随机推荐
- 如何设置body内容不能复制?
通过在body标签上设置相关的属性: <body oncontextmenu="return false" ondragstart="return false&qu ...
- 关于宝塔面板ftp+sublime
如果sublime通过ftp上传文件传不上去,我的问题在于应该把sftp-config.json中"remote_path": "/",设置成这样.一下午.哎呀 ...
- 解决:gradle 前言中不允许有内容
将Android Studio 升级到4.0然后创建一个新项目,编译出现“ gradle 前言中不允许有内容” 的错误,在网上找了很多资料,众说纷纭,但都没有解决我的问题,最后反复摸索把问题解决了. ...
- ojdbc6中OraclePreparedStatement的ArrayIndexOutOfBoundsException异常BUG-6396242
现场信息 Caused by: java.lang.ArrayIndexOutOfBoundsException: -32203 at oracle.jdbc.driver.OraclePrepare ...
- 【JMeter_07】JMeter逻辑控制器__循环控制器<Loop Controller>
循环控制器<Loop Controller> 业务逻辑: 根据所填写的循环次数,对当前节点下的取样器进行响应次数的循环请求,这里可以填写变量.整数.小数.字母.负数.各种符号等: 当填写整 ...
- ca70a_c++_重载函数_实参类型转换
/*ca70a_c++_重载函数_实参类型转换转换等级,详见P290 编译选择哪个函数版本呢?1.精确匹配2.通过类型提升3.通过标准转换4.通过类类型转换参数匹配和枚举类型重载和const形参 vo ...
- ASP.NET处理管道之防盗链
盗链就是在用户向网站a请求网站资源时,网站a将网站资源的路径填写为b网站资源的地址,用户将直接看到网站a上显示着网站b的资源,从而造成盗链. 要防止盗链,就要用到处理管道中的技术 在相应的模块类中: ...
- 【Java】错误: 需要class, interface或enum
今天在用cmd实现mvn package操作时跳出来的报错! 网上搜索到的结论是因为编码问题而产生的,具体原因就不深究了 要详细了解可以查看以下链接https://blog.csdn.net/qq_3 ...
- Spring Boot 分离资源文件打包
Spring Boot项目默认的会打包成单一的jar文件,但是有时候我们并不想让配置文件.依赖包都跟可执行文件打包到一起.这时候可以在pom.xml文件中进行配置,从而使资源文件.依赖包和可执行文件分 ...
- 为什么用抓包工具看HTTPS包是明文的
测试或者开发调试的过程中,经常会进行抓包分析,并且装上抓包工具的证书就能抓取 HTTPS 的数据包并显示.由此就产生了一个疑问,为什么抓包工具装上证书后就能抓到 HTTPS 的包并显示呢?不是说 HT ...