22)django-中间件
Posted 狼来的日子里!
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了22)django-中间件相关的知识,希望对你有一定的参考价值。
一:中间件介绍
django 中的中间件(middleware),在django中,中间件其实就是一个类,在请求到来和结束后,
django会根据自己的规则在合适的时机执行中间件中相应的方法。
在django项目的settings模块中,有一个 MIDDLEWARE_CLASSES 变量,其中每一个元素就是一个中间件。示例
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)时候是从上到下顺序执行,返回(process_response)是下到上执行。
示例图如下:
中间件中可以定义五个方法,分别是:
- 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)
以上方法的返回值可以是None和HttpResonse对象,如果是None,
则继续按照django定义的规则向下执行,如果是HttpResonse对象,则直接将该对象返回给用户。
三:自定义中间件
结合上面的5个方法观察中间件执行顺序。
自定义中间件需要继承:from django.utils.deprecation import MiddlewareMixin
1)process_request方法执行顺序
创建文件middle.m1.py
#middle.m1.py # -*- coding:utf-8 -*- __author__ = \'shisanjun\' from django.utils.deprecation import MiddlewareMixin class Row1(MiddlewareMixin): def process_request(self,request): #这就表示写了个中间件了 print(111) class Row2(MiddlewareMixin): def process_request(self,request): #这就表示写了个中间件了 print(222) class Row3(MiddlewareMixin): def process_request(self,request): #这就表示写了个中间件了 print(3333)
上面创建三个中间件,还需要在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\', \'middle.m1.Row1\', \'middle.m1.Row2\', \'middle.m1.Row3\', ]
测试views.py
def test(request): int("aaa") print("小姨妈") return HttpResponse("ok")
urls.py
url(r\'^test/\', views.test),
测试结果:
#结果 ====================================== 111 222 3333 小姨妈
执行顺序
2)中间件里有process_response(self, request, response),此方法需要返回return response,否则报错。
__author__ = \'shisanjun\' from django.utils.deprecation import MiddlewareMixin class Row1(MiddlewareMixin): def process_request(self,request): #这就表示写了个中间件了 print(111) def process_response(self,request,response): pass class Row2(MiddlewareMixin): def process_request(self,request): #这就表示写了个中间件了 print(222) def process_response(self,request,response): pass class Row3(MiddlewareMixin): def process_request(self,request): #这就表示写了个中间件了 print(3333) def process_response(self,request,response): pass 报错:这说明views有返回值,但是中间件没有取,process_response没有做处理,需要返回response AttributeError at /test/ \'NoneType\' object has no attribute \'get\'
修改如下:
修改: # -*- coding:utf-8 -*- __author__ = \'shisanjun\' from django.utils.deprecation import MiddlewareMixin class Row1(MiddlewareMixin): def process_request(self,request): #这就表示写了个中间件了 print(111) def process_response(self,request,response): print("到1了") return response class Row2(MiddlewareMixin): def process_request(self,request): #这就表示写了个中间件了 print(222) def process_response(self,request,response): print("到2了") return response class Row3(MiddlewareMixin): def process_request(self,request): #这就表示写了个中间件了 print(3333) def process_response(self,request,response): print("到3了") return response
结果:
#结果 Quit the server with CTRL-BREAK. 111 222 3333 小姨妈 到3了 到2了 到1了
执行顺序:
这里request和response就是view中的,所以request含有所有HTTP请求 中间有什么用了? 可以在中间件做一些判断,比如在中间件判断是不是有请求头,如果没有就不让往后面走(可以直接return HttpResponse) django,在1.10版本中在那个中间件返回,就从那个返回。 在1.7,1。8版本中不是,是在中间的中间件要求返回,但是还是会走到最后一个中间,再返回。 中间件适合什么操作了?对所有请求做统一的操作。
3)中间件里有process_view(self,request,view_func,view_args,view_kwargs):。
# -*- coding:utf-8 -*- __author__ = \'shisanjun\' from django.utils.deprecation import MiddlewareMixin class Row1(MiddlewareMixin): def process_request(self,request): #这就表示写了个中间件了 print(111) def process_view(self,request,view_func,view_args,view_kwargs): print("中间1") def process_response(self,request,response): print("到1了") return response class Row2(MiddlewareMixin): def process_request(self,request): #这就表示写了个中间件了 print(222) def process_view(self,request,view_func,view_args,view_kwargs): print("中间2") def process_response(self,request,response): print("到2了") return response class Row3(MiddlewareMixin): def process_request(self,request): #这就表示写了个中间件了 print(3333) def process_view(self,request,view_func,view_args,view_kwargs): print("中间3") def process_response(self,request,response): print("到3了") return response #结果 Quit the server with CTRL-BREAK. 111 222 3333 中间1 中间2 中间3 小姨妈 到3了 到2了 到1了 view_func就是view函数
顺序
4)中间件里有process_exception(self, request, exception)
class Row3(MiddlewareMixin): def process_request(self,request): #这就表示写了个中间件了 print(3333) def process_view(self,request,view_func,view_args,view_kwargs): print("中间3") def process_response(self,request,response): print("到3了") return response def process_exception(self, request, exception):#当view出错的时候执行 print("err")
比如 def test(request): int("aaa")#这里转换为整数,会报错,就会调用上面的process_exception print("小姨妈") return HttpResponse("ok")
5)中间件里有process_template_response(self,request,response)
class Row3(MiddlewareMixin): def process_request(self,request): #这就表示写了个中间件了 print(3333) def process_view(self,request,view_func,view_args,view_kwargs): print("中间3") def process_response(self,request,response): print("到3了") return response def process_exception(self, request, exception):#什么时候执行了,当views函数出错了,就执行了 if isinstance(exception,ValueError): print(9999) def process_template_response(self,request,response): #如果views中的函数返回对象中,具有render方法,就会执行。 print("process_template_response")
以上是关于22)django-中间件的主要内容,如果未能解决你的问题,请参考以下文章
django.core.exceptions.ImproperlyConfigured: Requested setting DEFAULT_INDEX_TABLESPACE的解决办法(转)(代码片段
Django 中间件使用 ajax 使用 HTTPS POST 引发 403 错误
django.core.exceptions.ImproperlyConfigured: Requested setting DEFAULT_INDEX_TABLESPACE的解决办法(转)(代码片段
Express实战 - 应用案例- realworld-API - 路由设计 - mongoose - 数据验证 - 密码加密 - 登录接口 - 身份认证 - token - 增删改查API(代码片段