先搞清楚django处理请求的流程
在分析中间件之前,我们首先要清楚Django处理请求的流程。
中间件可以在请求到达视图之前或响应返回之前执行一些操作,那么此时流程就可以简化。
| 请求到达服务器 | --> | 请求中间件处理 | --> | 视图处理请求 | --> | 响应中间件处理 |
请求处理:当一个HTTP请求到达Django服务器时,请求首先会通过一系列的中间件。这些中间件可以修改请求对象(request),或者根据某些条件决定是否继续处理请求。 视图处理:请求通过中间件后,会到达视图函数或视图类。视图处理请求并生成响应。 响应处理:响应生成后,会再次通过中间件,这些中间件可以修改响应对象(response),例如添加HTTP头部、设置cookies等。 发送响应:最后,响应被发送回客户端。
例子说明
下面,我通过一个非常简单的例子说明一下(代码逻辑很简单,就不做说明):
视图函数:
def middlewarefunc(request):
if request.data == 'DPT':
tem = '帅哥'
else:
tem = '美女'
return HttpResponse(tem)
中间件:
class Middleware(MiddlewareMixin):
def process_request(self, request): #请求中间件
request.data = 'DPT' #request本没有data属性,中间件在view函数执行前赋值
def process_response(self, request, response): #响应中间件
return HttpResponse('美女') #此时在中间件把这个响应将被直接发送给客户端,而不会调用视图函数,这就意味着不之前你做了什么,在最后都要返回‘美女’
也就是说,不论是在,请求还是响应中间件,如果返回一个HTTPresponse对象, 那么这个响应将被直接返回给客户端,视图函数不会被调用。
源码说明
下面我根据源码简单说明一下:
可以看到,我们在定义中间件class时,继承了一个叫MiddlewareMixin的父类,实际上在django的众多中间件中,都继承了该类。
class MiddlewareMixin:
def __call__(self, request): #这是中间件的入口点。当请求到达中间件时,Django会调用这个方法。
response = None
# hasattr函数时检查当前中间件对象是否有一个名为process_request的方法
if hasattr(self, 'process_request'):
response = self.process_request(request)
response = response or self.get_response(request)
if hasattr(self, 'process_response'):
response = self.process_response(request, response)
return response
response = response or self.get_response(request),这句是关键。
首先,要知道逻辑或运算符
or
的工作原理,如果第一个操作数是真值,那么结果就是第一个操作数;如果第一个操作数是假值,那么结果就是第二个操作数。所以,如果
response
变量仍然是None
(意味着process_request
没有返回任何响应),那么get_response
方法会被调用(get_response
方法用于获取视图函数的响应)。如果
get_response
返回一个响应,那么这个响应将被赋给response
变量。如果
get_response
也返回None
,那么response
将保持为None
。
本人也处于学习阶段,若有错位与不足请指出。