前面第一篇主要记录了Flask框架,从http请求发起,到返回响应,发生在server和app直接的过程。
里面有说到,Flask框架有设计了两种上下文,即应用上下文和请求上下文
官方文档里是说先理解应用上下文比较好,不过我还是觉得反过来,从请求上下文开始记录比较合适,所以这篇先记录请求上下文。
什么是请求上下文
通俗点说,其实上下文就像一个容器,包含了很多你需要的信息
request和session都属于请求上下文
request 针对的是http请求作为对象
session针对的是更多是用户信息作为对象
上下文的结构
说到上下文这个概念的数据结构,这里需要先知道,他是运用了一个Stack的栈结构,也就说,有栈所拥有的特性,push,top,pop等
请求上下文 ----- RequestContext
当一个请求进来的时候,请求上下文环境是如何运作的呢?还是需要来看一下源码
上一篇有讲到,当一个请求从server传递过来的时候,他会调用Flask的__call__方法,所以这里还是回到wsgi_app那部分去讲
下面是当wsgi_app被调用的时候,最一开始的动作,这里的ctx是context的缩写
class Flask(_PackageBoundObject):
# 省略一部分代码
def wsgi_app(self, environ, start_response):
ctx = self.request_context(environ) #上下文变量ctx被赋值为request_context(environ)的值
ctx.push() #
再来看下request_context是一个什么样的方法,看看源码
看他的返回值,他返回的其实是RequestContext类生成的一个实例对象,看字面意思就知道是一个请求上下文的实例对象了.
这里可以注意看下他的函数说明,他举了一个例子,非常简单,ctx先push,最后再pop,和用with的方法作用是一毛一样的
这其实就是一个请求到响应最简单的骨架,侧面反映了request的生命周期
class Flask(_PackageBoundObject):
#省略部分代码
def request_context(self, environ):
"""ctx = app.request_context(environ)
ctx.push()
try:
do_something_with(request)
finally:
ctx.pop()"""
return RequestContext(self, environ)
继续往下层看,RequestContext是从ctx.py模块中引入的,所以去找RequestContext的定义
class RequestContext(object):
"""The request context contains all request relevant information. It is
created at the beginning of the request and pushed to the
`_request_ctx_stack` and removed at the end of it. It will create the
URL adapter and request object for the WSGI environment provided.
Do not attempt to use this class directly, instead use
:meth:`~flask.Flask.test_request_context` and
:meth:`~flask.Flask.request_context` to create this object."""
#省略部分说明
def __init__(self, app, environ, request=None):
self.a