修改请求,即传送到 view 中的 HttpRequest 对象。 修改响应,即 view 返回的 HttpResponse 对象。
1. process_request 1. 执行时间 在视图函数之前执行 2. 参数 request 和视图中的request是同一个 3. 返回值 返回None 返回response对象 不执行后面中间的process_request方法和视图 直接执行当前值中间件的process_response方法 4. 执行顺序 按照注册的顺序执行 process_request 方法有一个参数 request,这个 request 和视图函数中的 request 是一样的。 process_request 方法的返回值可以是 None 也可以是 HttpResponse 对象。 返回值是 None 的话,按正常流程继续走,交给下一个中间件处理。 返回值是 HttpResponse 对象,Django 将不执行后续视图函数之前执行的方法以及视图函数,直接以该中间件为起点,倒序执行中间件,且执行的是视图函数之后执行的方法。 process_request 方法是在视图函数之前执行的。 当配置多个中间件时,会按照 MIDDLEWARE中 的注册顺序,也就是列表的索引值,顺序执行。 不同中间件之间传递的 request 参数都是同一个请求对象。 代码示例: from django.utils.deprecation import MiddlewareMixin from django.shortcuts import render, HttpResponse class MD1(MiddlewareMixin): def process_request(self, request): print("md1 process_request 方法。", id(request)) #在视图之前执行
process_view 1. 执行时间 在视图函数之前,process_request之后执行 2. 参数 request 是 HttpRequest 对象。 view_func 是 Django 即将使用的视图函数。 view_args 是将传递给视图的位置参数的列表。 view_kwargs 是将传递给视图的关键字参数的字典。 view_args 和 view_kwargs 都不包含第一个视图参数(request)。 3. 返回值 返回 None 正常执行 返回 response对象 不执行后面的process_view和视图,直接执行所有中间件的process_response方法 返回 view_func(request) Django 将不执行后续视图函数之前执行的方法,提前执行视图函数,然后再倒序执行视图函数之后执行的方法 4。执行顺序 按照注册的顺序执行 process_view 方法是在视图函数之前,process_request 方法之后执行的。 当最后一个中间件的 process_request 到达路由关系映射之后,返回到第一个中间件 process_view,然后依次往下,到达视图函数 代码示例: class MD1(MiddlewareMixin): def process_request(self, request,callback,callback_args,callback_kwargs): #callback 就是视图函数 #res = callback(request) print("md1 process_request 方法。", id(request)) #在视图之前执行 def process_response(self,request, response): :#基于请求响应 print("md1 process_response 方法!", id(request)) #在视图之后 return response def process_view(self,request, view_func, view_args, view_kwargs): print("md1 process_view 方法!") #在视图之前执行 顺序执行 #return view_func(request)
process_template_response(条件触发:视图返回的response有render方法) 1. 执行时间 在视图函数之后,process_response之前执行 2. 参数 3. 返回值 返回 response对象 4. 执行顺序 按照注册的倒序执行,执行完所有的process_template_response方法后执行response.render方法
process_exception(有条件触发:有错误才执行) 1. 执行时间 在视图函数之后,process_response之前执行 2. 参数 exception 错误对象 3. 返回值 返回 None 不对错误进行处理,交给下一个中间件进行处理 返回 response对象 下一个中间的process_exception不执行,直接执行所有中间件的process_response方法 4. 执行顺序 按照注册的倒序执行 代码示例: class MD1(MiddlewareMixin): def process_request(self, request): print("md1 process_request 方法。", id(request)) #在视图之前执行 def process_response(self,request, response): :#基于请求响应 print("md1 process_response 方法!", id(request)) #在视图之后 return response def process_view(self,request, view_func, view_args, view_kwargs): print("md1 process_view 方法!") #在视图之前执行 顺序执行 #return view_func(request) def process_exception(self, request, exception):#引发错误 才会触发这个方法 print("md1 process_exception 方法!") # return HttpResponse(exception) #返回错误信息
process_response 1. 执行时间 在视图函数之后执行 2. request, response request 和视图中的request是同一个 response 返回的response对象 3. 返回值 返回response对象 4. 执行顺序 按照注册的倒序执行 代码示例: class MD1(MiddlewareMixin): def process_request(self, request): print("md1 process_request 方法。", id(request)) #在视图之前执行 def process_response(self,request, response): :#基于请求响应 print("md1 process_response 方法!", id(request)) #在视图之后 return response
以上方法的返回值可以是None或一个HttpResponse对象,如果是None,则继续按照django定义的规则向后继续执行,如果是HttpResponse对象,则直接将该对象返回给用户。
当用户发起请求的时候会依次经过所有的的中间件,这个时候的请求时process_request,最后到达views的函数中,views函数处理后,在依次穿过中间件,这个时候是process_response,最后返回给请求者。
process_request可以干什么? -写一个中间件,不管前端用什么编码,在requset.data中都有post的数据 -频率限制(限制某个ip地址,一分钟只能访问5次) -登录认证(只要没登录,重定向到login路径)、 -记录用户访问日志(ip,时间,访问路径) process_response可以干什么?内部有response对象 -统一给所有(某几个路径)加cookie -统一给所有(某几个路径)加响应头 process_view 路由匹配成功和视图函数执行之前执行(callback就是视图函数) def process_view(self, request, callback, callback_args, callback_kwargs): # print(callback) # print(callback_args) # print(callback_kwargs) #在调用函数前执行点什么 res=callback(request) #在视图函数执行后做点什么 类似装饰器 print("中间件1的process_view") return res process_exception 视图函数出错,会执行它(全局异常捕获)(记录日志,哪个ip地址,访问哪个路径,出的错) # 全局异常捕获,返回4开头的 def process_exception(self, request, exception): print(exception) return render(request,'error.html')
1、执行完所有的request方法 到达视图函数。 2、执行中间件的其他方法 3、经过所有response方法 返回客户端。 注意:如果在其中1个中间件里 request方法里 return了值,就会执行当前中间的response方法,返回给用户 然后 报错。。不会再执行下一个中间件。
-写一个类,继承MiddlewareMixin #from django.utils.deprecation import MiddlewareMixin -里面写方法process_request等方法 -在setting中配置(注意,放在前和放在后) MIDDLEWARE = [ ... 'app01.mymiddle.MyMiddleware1', ... ]