django中间件
按照django流程来算,中间件(MIDDLEWARE)位于第二个,根据位置可以大概知道它是第一关,也就是请求过来之后先经过它,然后才往下执行,根据这个特性,能够知道它和防火墙差不多,提到防火墙,那么就应该知道一些简单的知识,没错:
你符合我的要求,我才让你通过;
如果需要统计什么,可以在我这设置(日志);
全局操作;
总之,我能想到只有这些,这些一般也够了,所以先看它是什么样的,打开你django项目中的settings文件,然后在里面找一个
MIDDLEWARE_CLASSES = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] django1.0以上版本,是这种格式 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.auth.middleware.SessionAuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ]
它的流程是这样的(https://docs.djangoproject.com/en/1.8/topics/http/middleware/)

根据上图可以看出,中间件的每一步都要有一个值,比如进来的时候是process_request,出去的时候是process_response,懵了?看下面
中间件就是一层层的"防火墙",当请求到来之后会逐一的经过"每道墙",然后如果有一道墙执行了return,那么请求将不会往下执行,直接返回出去; 如果请求进来的时候没有遇到return,那么它会执行到底,直到把所有的代码执行完之后,才会返回出去;
一句话概括:我要去厕所,没人拦我,我直接蹲坑,如果有人拦我,我直接离开!
理论部分先到这,接下来说如何去写:
首先新建一个.py文件,然后大概格式是这样

然后在这个文件里随便写几个类,下见代码:
""" 我的django没有MiddlewareMixin这个类,所以使用的时候先要定义一个, 如果你的有,可以直接 from django.utils.deprecation import MiddlewareMixin 这样去调用 """ 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 class Row1(MiddlewareMixin): def process_request(self,request): print("中间件1请求") def process_response(self,request,response): print("中间件1返回") return response class Row2(MiddlewareMixin): def process_request(self,request): print("中间件2请求") # return HttpResponse("走") def process_response(self,request,response): print("中间件2返回") return response class Row3(MiddlewareMixin): def process_request(self,request): print("中间件3请求") def process_response(self,request,response): print("中间件3返回") return response
然后把这个文件添加到settings文件里

然后启动服务,你会看到

可以看得出来中间件的顺序,如何知道它是先执行的呢?你可以在视图函数中打印一个东西,如下代码
#!/usr/bin/env python # -*- coding: utf-8 -*- __Author__ = 'Chen Chen' from django.shortcuts import HttpResponse,render def server(request): # return HttpResponse("this is server") print("这是 视图函数") # 添加 return render(request, "server.html")
然后启动服务,你会发现

这就证明了,中间件是在视图函数前执行的,当django流程执行完毕之后,他又返回出去,这就是中间件的作用。一般情况下,中间件用于全局操作,比如说黑白名单,比如说日志,比如说统计等等,均可以在中间件内实现。
根据官网得知,中间件还有一些其他的操作:
https://docs.djangoproject.com/en/1.8/topics/http/middleware/
官网给出的五种方法,第一个和第四个已经知道了,接下来看其他的
rocess_request(request) # 已知
process_view(request, view_func, view_args, view_kwargs)
process_template_response(request, response)
process_response(request, response) # 已知
process_exception(request, exception)
首先说
process_view(request, view_func, view_args, view_kwargs)
根据命名可以得知它是和视图相关的,那么如何操作呢?看代码
settings: MIDDLEWARE_CLASSES = [ ......................... 'my_django.mid.Row1', # 添加 ] views: from django.shortcuts import HttpResponse,render def server(request): # return HttpResponse("this is server") return render(request, "server.html")
from . views import server """ 我的django没有MiddlewareMixin这个类,所以使用的时候先要定义一个, 如果你的有,可以直接 from django.utils.deprecation import MiddlewareMixin 这样去调用 """ 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 class Row1(MiddlewareMixin): """官网提示 process_view(request, view_func, view_args, view_kwargs) """ def process_view(self,request, view_func, view_args, view_kwargs): print("这是来自于视图函数的内容%s"%server(request)) return
改完之后,运行程序,你会发现它执行了视图函数,通过打印可以得知,它把你视图函数里面的功能加了进来,这样就相当于你定义了个函数,然后在它里面执行

所有中间件都是这样操作的。
接下来看
process_exception(request, exception)
同样可以看出它是和错误相关的
views: from django.shortcuts import HttpResponse,render def server(request): # return HttpResponse("this is server") print("视图函数") int('sssdsfdfdf') # 模拟报错 return render(request, "server.html") mid: from django.shortcuts import HttpResponse """ 我的django没有MiddlewareMixin这个类,所以使用的时候先要定义一个, 如果你的有,可以直接 from django.utils.deprecation import MiddlewareMixin 这样去调用 """ 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 class Row1(MiddlewareMixin):
"""官网提示
process_exception(request, exception)
""" def process_exception(self,request, exception): return HttpResponse("你的视图函数报错了,我的process_exception替你把错误捕获了")
由此可以知道,它是专门为我们捕获视图错误的,既然可以返回字符串,那么同样也可以返回其他的实体页面(它。。如果你的视图函数没有报错,它是不执行的)
接下来还有一个
process_template_response(request, response)
模板,接下来看使用方法:
views: from django.shortcuts import HttpResponse class Foo(): def __init__(self,chen): self.chen=chen def render(self): return HttpResponse('这是类的返回值') def server(request): print("这是函数的返回值") obj=Foo(request) return obj mid: """ 我的django版本开始有点问题,我撞了1.0,可以直接调用中间件 """ from django.utils.deprecation import MiddlewareMixin # 直接调用 class Row1(MiddlewareMixin): """官网给出 process_template_response(request, response) """ def process_template_response(self,request, response): print("ok") return response
执行上面的结果可以看到


记住关键字:这个process_template_response(self,request, response)只有你的视图中有render函数(实际叫方法)才会执行,你会问,为什么单独的一个render函数无法执行?首先要明白什么叫方法,方法不就是类里面的函数吗?如果你单独一个函数,它不会认为你这是是一个方法,所以在中间件里面它默认的不执行,就像错误捕获一样,你带吗没报错,它就不会执行,别问为什么,因为源码就这样,如果想研究,可以自行研究!
所以说:在定义中间件的时候,常用的两种,也可以是全部用上,这没有硬性规定,只有看需求,一般如果要是都用,那么格式就是完整的,也就是带着五中方法全写上,这样比较好,也不好,还是那句废话:看需求!
posted on 2018-06-15 11:34 ArkhamKnight 阅读(73) 评论(0) 收藏 举报
浙公网安备 33010602011771号