中间件介绍
什么是中间件?
在视图函数执行之前和执行之后都可以做一些额外的操作, 本质上为一个自定义类, 类中定义了几个方法, Django 框架会在请求的特定的时间去执行这些方法.
在 settings.py 中的位置
- MIDDLEWARE = [
- 'django.middleware.security.SecurityMiddleware',
- 'django.contrib.sessions.middleware.SessionMiddleware',
- 'django.middleware.common.CommonMiddleware',
- 'django.middleware.csrf.CsrfViewMiddleware',
- 'django.contrib.auth.middleware.AuthenticationMiddleware',
- 'django.contrib.messages.middleware.MessageMiddleware',
- 'django.middleware.clickjacking.XFrameOptionsMiddleware',
- ]
自定义中间件
中间件可以定义五个方法
- process_request(self,request)
- process_view(self, request, view_func, view_args, view_kwargs)
- process_template_response(self,request,response)
- process_exception(self, request, exception)
- process_response(self, request, response)
返回值可以是 None 或一个 HttpResponse 对象,
如果是 None, 则继续按照 django 定义的规则向后继续执行,
如果是 HttpResponse 对象, 则直接将该对象返回给用户.
自定义一个中间件示例
- from django.utils.deprecation import MiddlewareMixin
- class MD1(MiddlewareMixin):
- def process_request(self, request):
- print("MD1 里面的 process_request")
- def process_response(self, request, response):
- print("MD1 里面的 process_response")
- return response
process_request
参数:
request: 这个 request 和视图函数中的 request 是一样的 (HttpRequest 对象)
返回值:
None : 按正常流程继续走, 交给下一个中间件处理,
HttpResponse 对象: Django 将不执行视图函数, 而将相应对象返回给浏览器.
执行顺序:
视图函数之前
注册顺序执行
总结 :
中间件的 process_request 方法是在执行视图函数之前执行的.
当配置多个中间件时, 会按照 MIDDLEWARE 中的注册顺序, 从前到后依次执行
不同中间件之间传递的 request 都是同一个对象
process_response
参数:
request : 这个 request 和视图函数中的 request 是一样的
response: 视图函数返回的 HttpResponse 对象.
返回值:
HttpResponse 对象
执行顺序:
视图函数之后
注册顺序倒序
总结 :
process_response 方法是在视图函数之后执行的, 并且顺序是 MD1 比 MD2 先执行.(此时 settings.py 中 MD2 比 MD1 先注册)
多个中间件中的 process_response 方法是按照 MIDDLEWARE 中的注册顺序倒序执行的,
- process_view
- process_view(self, request, view_func, view_args, view_kwargs)
参数:
request: 这个 request 和视图函数中的 request 是一样的 (HttpRequest 对象)
view_func : Django 即将使用的视图函数. (它是实际的函数对象, 而不是函数的名称作为字符串.)
view_args: 传递给视图的位置参数的列表.
view_kwargs: 传递给视图的关键字参数的字典. view_args 和 view_kwargs 都不包含第一个视图参数 (request).
返回值
None: Django 将继续处理这个请求, 执行任何其他中间件的 process_view 方法, 然后在执行相应的视图.
HttpResponse 对象: Django 不会调用适当的视图函数. 它将执行中间件的 process_response 方法并将应用到该 HttpResponse 并返回结果.
执行顺序
调用视图函数之前调用 process_view 方法.
process_request 之后
注册顺序正序
- process_exception
- process_exception(self, request, exception)
参数:
request : 这个 request 和视图函数中的 request 是一样的 (HttpRequest 对象)
exception: 视图函数异常产生的 Exception 对象.
返回值:
None: 交给下一个中间件的 process_exception 方法 来处理异常.
HttpResponse 对象: 往下执行 process_response 方法, 并返回给浏览器, 否则将默认处理异常
执行顺序:
视图函数中出现异常了才执行, 即视图函数之后执行
process_response 方法执行前执行
注册顺序的倒序执行
- process_template_response(用的比较少)
- process_template_response(self, request, response)
参数:
request : 这个 request 和视图函数中的 request 是一样的 (HttpRequest 对象)
response : TemplateResponse 对象 (由视图函数或者中间件产生)
返回值:
HttpResponse 对象: 直接返回响应对象结果给浏览器, 不再执行后面的方法
执行顺序
视图函数执行完成后立即执行
前提条件: 那就是视图函数返回的对象有一个 render() 方法 (或者表明该对象是一个 TemplateResponse 对象或等价方法).
process_response 之前
注册顺序倒叙
中间件的执行流程
请求到达中间件之后, 先按照正序执行每个注册中间件的 process_reques 方法,
process_request 方法返回的值是 None, 就依次执行,
如果返回的值是 HttpResponse 对象, 不再执行后面的 process_request 方法, 而是执行当前对应中间件的 process_response 方法, 将 HttpResponse 对象返回给浏览器.
如图:
执行过程中, 第 3 个中间件返回了一个 HttpResponse 对象,
那么第 4,5,6 中间件的 process_request 和 process_response 方法都不执行,
往下顺序执行 3,2,1 中间件的 process_response 方法.
process_request 方法都执行完后, 匹配路由, 找到要执行的视图函数,
执行视图函数前, 先执行 process_view 方法,
process_view 方法返回 None, 继续按顺序执行, 所有 process_view 方法执行完后执行视图函数.
process_view 方法返回 HttpResponse 对象 (加入中间件 3 的 process_view 方法返回了 HttpResponse 对象)
则 4,5,6 的 process_view 以及视图函数都不执行, 直接从最后一个中间件, 也就是中间件 6 的 process_response 方法开始倒序执行.
process_template_response 和 process_exception 两个方法的触发是有条件的, 执行顺序也是倒序.
总结所有的执行流程如下:
中间件版登录验证
中间件版的登录验证需要依靠 session, 所以数据库中要有 django_session 表.
urls.py
urls.py
views.py
views.py
login.html
login.HTML
middlewares.py
登录校验中间件
在 settings.py 中注册
settings.py 中注册中间件
AuthMD 中间件注册后, 所有的请求都要走 AuthMD 的 process_request 方法.
访问的 URL 在白名单内或者 session 中有 user 用户名, 则不做阻拦走正常流程;
如果 URL 在黑名单中, 则返回 This is an illegal URL 的字符串;
正常的 URL 但是需要登录后访问, 让浏览器跳转到登录页面.
注: AuthMD 中间件中需要 session, 所以 AuthMD 注册的位置要在 session 中间的下方.
Django 请求流程图
来源: http://www.bubuko.com/infodetail-2944537.html