Django(47)drf请求生命周期分析
前言
一般我们写完序列化以后,我们就会开始写视图了,drf
中我们一般使用CBV
的方式,也就是类视图的方式,最基础的我们会使用from rest_framework.views import APIView
,APIView
继承自View
,关于视图的详解,我们后续再细讲。本章介绍drf
的请求生命周期
前置准备工作
我们先写一个视图类TestView
,代码如下:
from rest_framework.views import APIView
from rest_framework.response import Response
class TestView(APIView):
def get(self, request, *args, **kwargs):
return Response("drf get ok")
def post(self, request, *args, **kwargs):
return Response("drf post ok")
注意:这里的Response
必须是drf下的Response
,不能是Django原生的HttpResponse
或者是JsonResponse
,否则会出错
接着,在urls.py
中配置路由,如下
urlpatterns = [
path('test/', views.TestView.as_view(), name="Test"),
]
然后我们访问http://127.0.0.1:8000/drf/test/
,会出现下图样式,代表请求成功
接着我们在接口工具中使用POST
请求方式访问,返回结果如下:
"drf post ok"
以上2种访问方式都成功了,接下来我们分析其中的请求过程以及原理
请求生命周期分析
首先我们先从路由配置中看到views.TestView.as_view()
,调用的是TestView
类视图下的as_view
方法,但是我们上面定义该方法的时候,没有重写as_view()方法
,所以会调用父类APIView
中的as_view
方法,源码如下:
@classmethod
def as_view(cls, **initkwargs):
"""
Store the original class on the view function.
This allows us to discover information about the view when we do URL
reverse lookups. Used for breadcrumb generation.
"""
# 判断queryset是否是QuerySet对象
if isinstance(getattr(cls, 'queryset', None), models.query.QuerySet):
def force_evaluation():
raise RuntimeError(
'Do not evaluate the `.queryset` attribute directly, '
'as the result will be cached and reused between requests. '
'Use `.all()` or call `.get_queryset()` instead.'
)
cls.queryset._fetch_all = force_evaluation
# 调用父类的as_view方法
view = super().as_view(**initkwargs)
view.cls = cls
view.initkwargs = initkwargs
# Note: session based authentication is explicitly CSRF validated,
# all other authentication is CSRF exempt.
# 禁用了csrf认证
return csrf_exempt(view)
通过这行代码view = super().as_view(**initkwargs)
,可以知道APIView
的as_view
方法也调用了父类View
的as_view
方法,源码如下:
def as_view(cls, **initkwargs):
"""Main entry point for a request-response process."""
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. as_view "
"only accepts arguments that are already "
"attributes of the class." % (cls.__name__, key))
def view(request, *args, **kwargs):
self = cls(**initkwargs)
# 如果有get属性,没有head属性,那么head就是get
if hasattr(self, 'get') and not hasattr(self, 'head'):
self.head = self.get
# 初始化所有视图方法共享的属性
self.setup(request, *args, **kwargs)
# 如果没有request属性,报异常
if not hasattr(self, 'request'):
raise AttributeError(
"%s instance has no 'request' attribute. Did you override "
"setup() and forget to call super()?" % cls.__name__
)
# 返回一个`dispatch`方法
return self.dispatch(request, *args, **kwargs)
view.view_class = cls
view.view_initkwargs = initkwargs
# take name and docstring from class
update_wrapper(view, cls, updated=())
# and possible attributes set by decorators
# like csrf_exempt from dispatch
update_wrapper(view, cls.dispatch, assigned=())
return view
as_view
方法返回的是view
,view
返回的是dispatch
方法,dispatch
方法也是调用的APIView
下的dispatch
方法,源码如下:
def dispatch(self, request, *args, **kwargs):
"""
`.dispatch()` is pretty much the same as Django's regular dispatch,
but with extra hooks for startup, finalize, and exception handling.
"""
self.args = args
self.kwargs = kwargs
# 初始化请求,返回的是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
# 获取request的请求方法
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
response = handler(request, *args, **kwargs)
except Exception as exc:
# 在调用方法处理程序之前出现异常,则跑出异常
response = self.handle_exception(exc)
# 返回一个response响应对象
self.response = self.finalize_response(request, response, *args, **kwargs)
return self.response
dispatch
返回一个response
响应对象,得到请求的响应结果,返回给前台
总结
- url请求走的是
APIView
的as_view
函数 - 在
APIView
的as_view
调用父类(django原生)的as_view
,还禁用了csrf
认证 - 在父类的
as_view
中的dispatch
方法请求走的又是APIView
的dispatch
- 完成任务方法交给视图类函数处理,得到请求的响应结果,返回给前台
Django(47)drf请求生命周期分析的更多相关文章
- DRF框架(一)——restful接口规范、基于规范下使用原生django接口查询和增加、原生Django CBV请求生命周期源码分析、drf请求生命周期源码分析、请求模块request、渲染模块render
DRF框架 全称:django-rest framework 知识点 1.接口:什么是接口.restful接口规范 2.CBV生命周期源码 - 基于restful规范下的CBV接口 3.请求组件 ...
- drf复习(一)--原生djangoCBV请求生命周期源码分析、drf自定义配置文件、drf请求生命周期dispatch源码分析
admin后台注册model 一.原生djangoCBV请求生命周期源码分析 原生view的源码路径(django/views/generic/base.py) 1.从urls.py中as_view ...
- Django(35)Django请求生命周期分析(超详细)
Django请求生命周期分析 1.客户端发送请求 在浏览器输入url地址,例如www.baidu.com,浏览器会自动补全协议(http),变为http://www.baidu.com,现在部分网站都 ...
- DRF 请求生命周期以及各模块解析
目录 rest_framework框架的封装特点 原生Django与DRF比较 APIView 的请求生命周期 请求模块(request) 解析模块(parser_classes) 异常模块(exce ...
- Django简介,请求生命周期,静态文件配置
Web框架 Web框架(Web framework)是一种开发框架,用来支持动态网站.网络应用和网络服务的开发.这大多数的web框架提供了一套开发和部署网站的方式,也为web行为提供了一套通用的方 ...
- drf框架概况-resful接口规范-请求模块-渲染模块-Postman-drf请求生命周期
drf框架 全称:django-rest- framework 知识点: """ 1.接口:什么是接口.restful接口规范 2.CBV生命周期源码-基于restful ...
- 3) drf 框架生命周期 请求模块 渲染模块 解析模块 自定义异常模块 响应模块(以及二次封装)
一.DRF框架 1.安装 pip3 install djangorestframework 2.drf框架规矩的封装风格 按功能封装,drf下按不同功能不同文件,使用不同功能导入不同文件 from r ...
- Django框架深入了解_01(Django请求生命周期、开发模式、cbv源码分析、restful规范、跨域、drf的安装及源码初识)
一.Django请求生命周期: 前端发出请求到后端,通过Django处理.响应返回给前端相关结果的过程 先进入实现了wsgi协议的web服务器--->进入django中间件--->路由f分 ...
- APIview的请求生命周期源码分析
目录 APIview的请求生命周期源码分析 请求模块 解析模块 全局配置解析器 局部配置解析器 响应模块 异常处理模块 重写异常处理函数 渲染模块 APIview的请求生命周期源码分析 Django项 ...
随机推荐
- Ansible(1)- 简单介绍
什么是 Ansible 开源部署工具,也是一个自动化运维工具 开发语言:Python Ansible 的特性 模块化部署管理:调用特定的模块,完成特定任务 三个关键模块:Paramiko(python ...
- 开源Influxdb2高性能客户端
前言 最近我在了解时序数据库Influxdb 2.x版本,体验一翻之后,感觉官方的出品的.net客户端还有很多优化的地方,于是闭关几天,不吃不喝,将老夫多年练就的高性能网络通讯与高性能Buffer操作 ...
- vue项目打包本地后通过nginx解决跨域
前言 有时候我们打包好vue项目让后端人员部署项目时可能会有小插曲,为了不麻烦后端人员和避免尴尬,最好的办法就是在本地自己先测一下,而在本地运行打包后的项目会遇到接口跨域的问题.我平时经常用的方法就是 ...
- go gin框架和springboot框架WEB接口性能对比
1 简要概述 最近看起go lang,真的被go的goroutine(协程)惊艳到了,一句 go function(){#todo},即可完成一个并发的工作. 看到gin这个web框架时,突然就特别想 ...
- hdu4849 最短路
题意: 让你求0到所有点最短路中对m取余最小的那个数. 思路: 简单题,直接根据题目给的公式把z求出来,然后建边,然后最短路,然后枚举每一个点对m取余记录最小,然后输出答案,然 ...
- 远程连接mysql出现"Can't connect to MySQL server 'Ip' ()"的解决办法
1.大多是防火墙的问题(参考链接:https://blog.csdn.net/jiezhi2013/article/details/50603366) 2.上面方法不能解决,不造成影响情况下可关闭防火 ...
- pyhive的基本使用
安装 yum -y install cyrus-sasl cyrus-sasl-devel cyrus-sasl-lib # 解决报错:sasl/sasl.h: No such file or di ...
- Http协议有什么特点,能说说这些特点体现在哪些方面吗?
Http协议有什么特点,能说说这些特点体现在哪些方面吗? Http协议是我们最常用的接口,那它有什么特点呢? 无连接 无状态 还有呢? 灵活,简单快速 还有它的这些特点体现在哪些方面?你也要能说一说. ...
- 使用C#进行数据库增删改查ADO.NET(一)
这节讲一下如何使用C#进行数据库的增删改查操作,本节以SQL Server数据库为例. .NET 平台,使用ADO.NET 作为与数据库服务器的桥梁,我们通过ADO.NET就可以使用C#语言操作数据库 ...
- SparkSQL电商用户画像(四)之电商用户画像数据仓库建立
六. 电商用户画像数据仓库建立 7.1 数据仓库准备工作 为什么要对数据仓库分层?星型模型 雪花模型 User----->web界面展示指标表 l 用空间换时间,通过大量的预处理来提升 ...