Django中间件
Django中间件
HTTP请求周期初识
在HTTP请求周期中,之前的了解是:用户请求->URL->view视图->url->用户
实际在用户请求和URL之间是中间件
Django 的中间件的本质是类,有几个中间件,就有经过几个类,每个类都有相应的方法。
Django中的中间件
Django的中间件在setting中MIDDLEWARE
中间件是有顺序的,按照setting中的从上到下顺序执行
在Django1.10
以上的版本中,当请求从上到下执行,如到达csrf出现问题,会从同一级别的csrf返回。
在之前的版本中,请求到达csrf出现问题,会从最后一个中间件返回。
自定义中间件
可以在当前的中间件的基础上进行修改,也可以自己定制新的中间件
小功能:
-
比如,黑名单功能,请求来的时候判断用户的IP是否在黑名单中,如果在,禁止请求
-
在中间件中添加装饰器判断用户是否登录
自定义中间件:
- 继承MiddlewareMixin
- process_request 可以没有返回值,有返回值的时候直接从同级别的位置返回
- process_response 有三个参数,必须有返回值
中间件
from django.utils.deprecation import MiddlewareMixin
class M1(MiddlewareMixin):
def process_request(self, request):
print("m1.request")
def process_response(self, request, response): # 还有一个response参数
print("m1.response")
return response
视图
from django.shortcuts import render,redirect,HttpResponse
def test(rquest):
print('test')
return HttpResponse("ok")
结果:
m1.request
test 视图函数的执行
m1.response
process_request有返回值的情况
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import render,redirect,HttpResponse
class M1(MiddlewareMixin):
def process_request(self, request):
print("m1.request")
return HttpResponse('okokoko') # 这里添加了返回值
def process_response(self, request, response): # 还有一个response参数
print("m1.response")
return response
结果:没有执行视图函数
m1.request
m1.response 直接从自己的方法返回
注册中间件
按顺序执行
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',
# 'md.M1',
# 'md.M2',
'm1.M1', # 自己的中间件 文件名+类名
]
深入HTTP请求周期
首选要明白的是web框架的本质是socket,但是Django是没有的,默认的wsgiref,生产环境用的是uwsgi
WSGI(Web Server Gateway Interface)Web服务网关接口已经成为了一种规范
wsgi是Django开始的地方
自定义中间件view
下面的情况是执行完m1的request后执行m2的request.
执行view的时候重新返回m1的view,然后是m2的view
中间执行view视图函数
最后执行m2的response,m1的response
from django.utils.deprecation import MiddlewareMixin
class M1(MiddlewareMixin):
def process_request(self, request):
print("m1.process_request")
def process_view(self, request, callback, callback_args, callback_kwargs):
print("m1.process_view")
def process_response(self, request, response):
print("m1.process_response")
return response # response必须要有返回值
class M2(MiddlewareMixin):
def process_request(self, request):
print('m2.process_request')
def process_view(self, request, callback, callback_args, callback_kwargs):
print("m2.process_view")
def process_response(self, request, response):
print('m2.process_response')
return response #
结果:
m1.process_request
m2.process_request
m1.process_view
m2.process_view
test
m2.process_response
m1.process_response
*在view中是用callback方法
通过callback找到了视图函数的名字,callback加括号就是执行视图函数一次
注意的是m1的process_view没有返回值的时候是执行一次view中的test函数
有返回值的时候m2的process_view不会执行
from django.utils.deprecation import MiddlewareMixin
class M1(MiddlewareMixin):
def process_request(self, request):
print("m1.process_request")
def process_view(self, request, callback, callback_args, callback_kwargs):
print("m1.process_view")
response = callback(request, *callback_args, **callback_kwargs)
# 这里是找函数 url对应的函数名
# return response 有response的时 从这里返回
def process_response(self, request, response):
print("m1.process_response")
return response # response必须要有返回值
class M2(MiddlewareMixin):
def process_request(self, request):
print('m2.process_request')
def process_view(self, request, callback, callback_args, callback_kwargs):
print("m2.process_view")
def process_response(self, request, response):
print('m2.process_response')
return response #
结果:
m1.process_request
m2.process_request
m1.process_view
test # 这是callback执行的
m2.process_view
test
m2.process_response
m1.process_response
process的方法
- process_request
- process_response 一定要有返回值
- process_view
- process_exception(错误异常)
- process_template
- 视图函数中有render方法才执行
- 自己写类进行封装
返回对象有render方法
process_request(self,request)
process_view(self, request, callback, callback_args, callback_kwargs)
process_template_response(self,request,response)
process_exception(self, request, exception)
process_response(self, request, response)
中间件应用
对所有请求或一部分请求做批量处理
例如把所有的请求筛选,缓存中有,直接从缓存中拿