request请求生命周期
request请求生命周期
一、request请求分析
1.1. request数据请求
# views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from django.http.request import QueryDict
class BookAPIView(APIView):
def get(self, request, *args, **kwargs):
print(request._request.GET) # 原生wigs中值
print(request.GET) # 二次封装的值
print(request.META) # 所有get请求信息
print(request.META.get("HTTP_AUTH")) # 前台发来的头都会大写并加上HTTP
print(request.query_params) # 所有url数据
print(request.POST) # get请求不能获取Post请求数据
return Response('get ok')
def post(self, request, *args, **kwargs):
print(request._request.POST) # 原生wigs中值
print(request.POST) # 二次封装的值
print(request.data) # 所有post请求数据
print(request._request) # url数据包<WSGIRequest: POST '/books/?age=123'>
print(request.GET) # POST请求可以Post请求数据
# QueryDict转为
print(request.query_params.dict())
if isinstance(request.data, QueryDict):
print(request.data.dict())
return Response('post ok')
# urls.py
from . import views
urlpatterns = [
url(r'^books/$', views.BookAPIView.as_view()),
]
总结:
- drf中的request是在wsgi的request基础上进行再一次封装
- 将wsgi的request作为drf的request的一个属性,
_request
- drf中的request对wsgi中的request做完全兼容,新的可以直接获取wsgi中的数据
- drf中的request对数据解析更规范化,所有的拼接参数(url?age=18)都解析到了query_params中,所有数据报数据都解析到data中
- query_params和data属于QueryDict类型,可以通过.dict()转化为字典类型
二、request请求源码分析
# 1. 2. urls.py
from . import views
urlpatterns = [
url(r'^books/$', views.BookAPIView.as_view()),
]
#3.调用drf中的as_view
@classmethod
def as_view(cls, **initkwargs): # cls 为 views.BookAPIView类
...
view = super().as_view(**initkwargs) # as_view原生的as_view,super() 为 view
view.cls = cls
view.initkwargs = initkwargs
return csrf_exempt(view)
# 4.进入drf中dispatch
def dispatch(self, request, *args, **kwargs): # self为views.BookAPIView类
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
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)
self.response = self.finalize_response(request, response, *args, **kwargs)
return self.response
# 4.1 返回封装的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
)
# 5.Request类创建 self._request = request自己的属性
def __init__(self, request, parsers=None, authenticators=None,
negotiator=None, parser_context=None):
assert isinstance(request, HttpRequest), (
.format(request.__class__.__module__, request.__class__.__name__)
)
self._request = request
self.parsers = parsers or ()
self.authenticators = authenticators or ()
self.negotiator = negotiator or self._default_negotiator()
self.parser_context = parser_context
#6.如何实现获取wgis中的属性
def __getattr__(self, attr):
"""
If an attribute does not exist on this instance, then we also attempt
to proxy it to the underlying HttpRequest object.
"""
try:
return getattr(self._request, attr)
except AttributeError:
return self.__getattribute__(attr)
导入drf中的APIView并创建类继承它,在配置url:
url(r'^books/$', views.BookAPIView.as_view()),
当项目启动时会执行drf中的as_view()方法,返回view方法(局部禁用了csrf认证), url:
url(r'^books/$', views.BookAPIView.view
浏览器发送请求来时则会执行url中view函数,在执行view中返回的是
self.dispatch(request, *args, **kwargs)
, dispatch是drf中的dispatch, 不是wsgi中原生的dispatch进入drf中的dispatch首先会对原生的request进行二次封装:
request = self.initialize_request(request, *args, **kwargs)
,在initialize_request
方法中返回了一个request实例对象进入request.py中的Request方法中就会发现在初始化方法中将wsgi方法的request变为了自己的一个属性: 'self._request = request'
request通过反射的方法获取wsgi中request属性,当request.获取属性先到 _request中查找,没有则查自己本身的
#6.如何实现获取wgis中的属性
def __getattr__(self, attr):
"""
If an attribute does not exist on this instance, then we also attempt
to proxy it to the underlying HttpRequest object.
"""
try:
return getattr(self._request, attr)
except AttributeError:
return self.__getattribute__(attr)
核心
- 走drf的Request初始化方法__init__:self._request = request
- drf的Request的getter方法__getattr__:先从self._request反射取属性,没取到再从drf的request中取
- request除了可以访问原wsgi协议的request所有内容,还可以访问 query_params、data
request请求生命周期的更多相关文章
- laravel中的$request对象构造及请求生命周期
laravel应用程序中index.php是所有请求的入口.当用户提交一个form或者访问一个网页时,首先由kernel捕捉到该session PHP运行环境下的用户数据, 生成一个request对象 ...
- jsp当做第二个servlet request的生命周期 请求 响应 不管中间经历多少个servlet 只要最后一个serlvt执行后 则生命周期结束 request的域消失
jsp当做第二个servlet request的生命周期 请求 响应 不管中间经历多少个servlet 只要最后一个serlvt执行后 则生命周期结束 request的域消失
- DRF框架(一)——restful接口规范、基于规范下使用原生django接口查询和增加、原生Django CBV请求生命周期源码分析、drf请求生命周期源码分析、请求模块request、渲染模块render
DRF框架 全称:django-rest framework 知识点 1.接口:什么是接口.restful接口规范 2.CBV生命周期源码 - 基于restful规范下的CBV接口 3.请求组件 ...
- [Django框架 - 静态文件配置、request对象方法初识、 pycharm链接数据库、ORM实操增删改查、django请求生命周期]
[Django框架 - 静态文件配置.request对象方法初识. pycharm链接数据库.ORM实操增删改查.django请求生命周期] 我们将html文件默认都放在templates文件夹下 将 ...
- Request Session生命周期及struts1 中service的编写
现在接手的项目是一个早期的struts1框架的项目.同时也是刚开始接触web 以及struts1架构. 在处理多个action时,有一个tab子页面需要每5s自动刷新一次. 然后在测试过程中发现,点击 ...
- 详解ASP.NET MVC应用程序请求生命周期
------转载当一个ASP.NET MVC应用程序提出请求,为了响应请求,包含一些请求执行流程步骤! 在ASP.NET MVC应用程序Http request 和Http response 过程中, ...
- django请求生命周期,FBV和CBV,ORM拾遗,Git
一.django 请求生命周期 流程图: 1. 当用户在浏览器中输入url时,浏览器会生成请求头和请求体发给服务端请求头和请求体中会包含浏览器的动作(action),这个动作通常为get或者post, ...
- Django(十一)请求生命周期之响应内容(请求/响应 头/体)
https://www.cnblogs.com/renpingsheng/p/7534897.html Django请求生命周期之响应内容 http提交数据的方式有"post",& ...
- $Django orm增删改字段、建表 ,单表增删改查,Django请求生命周期
1 orm介绍 ORM是什么 ORM 是 python编程语言后端web框架 Django的核心思想,“Object Relational Mapping”,即对象-关系映射,简称ORM. 一 ...
随机推荐
- Kubernetes-基于helm安装部署高可用的Redis及其形态探索
首先是一些关于redis的介绍和其在K8S上的安装过程:https://www.kubernetes.org.cn/3974.html 1.1部署形态 通过上述地址的教程,可以完成redis 的安装和 ...
- web应用中并发控制的实现,各种锁的集合
参考:http://blog.csdn.net/xiangwanpeng/article/details/55106732 B/S构架的应用越来越普及,但由于它有别于C/S构架的特殊性,并发控制始终没 ...
- 2020年9大顶级Java框架
诞生于1995年的Java,目前已在134,861个网站上广泛使用,包括ESPN.SnapDeal等.在其24年的成长史中,Java已经证明了自己是用于自定义软件开发的顶级通用编程语言. Java广泛 ...
- mysql初始化出现:FATAL ERROR: Neither host 'DB01' nor 'localhost' could be looked up with
初始化时: FATAL ERROR: Neither host 'DB01' nor 'localhost' could be looked up with /application/mysql/bi ...
- 组件state
一.设计合适的state 1.1 定义: state代表一个组件UI呈现的完整状态 stae代表一个组件UI呈现的最小状态集[所有状态都用于组件UI的变化,没有任何多余的状态] 1.2 state和p ...
- GitHub上传家庭记账本
GitHub的使用参考之前的博客GitHub的初步了解和使用,并完成了相关的android个人家庭记账本的上传
- JS-语句三
关于if语句的几个练习: 1. 输入三个整数,x,y,z,最终以从小到大的方式输出. 思路:先列举出每种可能,然后做if套嵌. var x = prompt("请输入一个数字 ...
- [C/C++]'fopen': This function or variable may be unsafe
这个错误也算比较常见吧,当然这个与代码无关,是编译器的问题,主要是VS中出现的,因为微软方面认为fopen函数是不安全的,于是自己搞了一套fopen_s的函数来代替,用前面一个的话编译器是会出错的,所 ...
- 改变UILable里面文字的大小和颜色
UILabel *lb = [[UILabel alloc]init]; NSMutableAttributedString *attriStr = [[NSMutableAttributedStri ...
- awk 中 RS,ORS,FS,OFS 区别与联系
一,RS与ORS 1,RS是记录分隔符,默认的分隔符是\n,具体用法看下 [root@krlcgcms01 mytest]# cat test1 //测试文件 111 222 333 444 ...