django处理一个Request的过程是首先通过django 中间件,然后再通过默认的URL方式进行的。所以说我们要做的就是在django 中间件这个地方把所有Request拦截住,用我们自己的方式完成处理以后直接返回Response,那么我们可以简化原来的设计思路,把中间件不能处理的 Request统统不管,丢给Django去处理
中间件的安装
直接在django配置里面添加如下配置,Django本来就配置类好多中间件,中间件的执行顺序从上到下依次进行
MIDDLEWARE = [
'md.middleware.M1', # 自定义的中间件
'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',
]
自定义中间件
其实每一个中间件都是一个类,类里面的方法django已经帮我们规定好了
from django.utils.deprecation import MiddlewareMixin
class M1(MiddlewareMixin):
# 方法和参数必须要按照人家的规定的写
def process_request(self, request):
print('process_request') # 注意,request没有返回值
def process_response(self, response):
print('process_response')
return response
这样,django运行起来之后会先打印process_request,然后执行视图函数,视图函数执行完毕之后最后执行M1里面的process_response方法,也就是打印process_response
注意:如果新版本的django不能导入中间件的话,完全可以自己写模块
class MiddlewareMixin(object):
def __init__(self, get_response=None):
self.get_response = get_response
super(MiddlewareMixin, self).__init__()
def __call__(self, request):
response = None
if hasattr(self, 'process_request'):
response = self.process_request(request)
if not response:
response = self.get_response(request)
if hasattr(self, 'process_response'):
response = self.process_response(request, response)
return response
将这段代码放到自己定义的中间键前面就可以了
中间件和装饰器的区别
中间件是针对所有的请求和返回,而装饰器只是针对某个函数的,装饰器的粒度更小一些
中间件的方法
Django的中间件就是一个类,类里面有五个方法
- process_request 请求刚进来执行的方法,
- process_response 请求回去的时候执行的方法,必须要有返回值
- process_view 路由匹配,等最后一个request执行完毕后会跳到第一个路由匹配进行执行
- process_exception 程序报错执行所有中间件的exception方法,从最后一个开始一直执行到第一个然后再返回到最后一个response执行
- process_tempalte_response
方法返回值
-
process_request 此方法不能有返回值,如果有返回值会直接执行与他平行的response,下面的不会执行 ,但是也可以对请求值进行判断,然后相应的复合条件的返回,不符合条件的不返回,也可以return None,和没有返回值是一个效果
-
process_response 必须要有返回值,因为他就是请求返回的时候执行的,没有返回值一定会报错,但是我们可以对返回值进行一定的修改
-
process_view 如果有返回值,会跳到最后一个response返回
-
process_exception 如果某个中间件捕捉到错误且返回值的话,直接跳到最后一个response执行
应用场景
由于中间件的特性,他的应用很广也很灵活
用户验证
class M1(MiddlewareMixin):
if request.path_info == '/login/':
return None
# 方法和参数必须要按照人家的规定的写
def process_request(self, request):
if not request.session.get('user_info'):
return redirect('/login/')
def process_response(self, response):
print('process_response')
return response
注意:
-
这个方法用到了session,session也是一个中间件,因此我们在安装这个中间件的时候必须要放在session中间件的下面,最好放在最下面
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware', # session中间件
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware',
'md.middleware.M1', # 放在session中间件下面
] -
注意前面对request.path_info的判断,如果不加这个判断的话,跳转login页面的时候又会进行一次判断session,如果不符合继续跳转,就会形成死循环,加这个判断的一次是,如果判断当前路径为login的话返回None,也就是继续执行。
网友评论