以下图是客户端发起一次http请求的流程:
注意:django框架不包括socket,要借助图中两个模块实现socket,进行客户端和服务器通信。wsgi性能较弱,一般测试开发用;企业中用uwsgi比较好,性能强,并发好
。
上图可知,在请求到达视图之前,会依次执行中间件,视图返回的响应,依次倒序执行中间件
。
django 中间件(middleware),在django中其实就是一个类
,在请求到来和结束后,django会根据自己的规则在合适的时机执行中间件中相应的方法。
在django项目的setting.py文件中,有一个MIDDLEWARE列表,其中每一个元素都是一个中间件
MIDDLEWARE_CLASSES = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'qinspect.middleware.QueryInspectMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'corsheaders.middleware.CorsMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
" style="">
在setting.py中注册中间件:
MIDDLEWARE_CLASSES = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'qinspect.middleware.QueryInspectMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'corsheaders.middleware.CorsMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'libs.api_tools.middleware.CustomizeMiddleware' 创建的自定义中间件类(路径 + 类名)
]
注意:django 1.10之后django无法导入,因此直接把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 CustomizeMiddleware(MiddlewareMixin): 自定义类,继承MiddlewareMixin
......
同样也是在setting.py中注册中间件:
MIDDLEWARE_CLASSES = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'qinspect.middleware.QueryInspectMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'corsheaders.middleware.CorsMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'libs.api_tools.middleware.CustomizeMiddleware' 创建的自定义中间件类(路径 + 类名)
]
process_request 请求进来时执行;
不能有返回值,若在process_request有返回值,那么下面的中间件将不会执行,后面的URL以及视图函数也不会执行,直接执行当前的中间件的process_response方法。
请求时,仅让IP为192.168.1.1才可以进行访问
from django.shortcuts import HttpResponse
class CustomizeMiddleware(MiddlewareMixin):
def process_request(self, request, response):
allowed_ip = ['192.168.1.1',]
允许/禁止访问的ip地址列表,判断请求ip, 放行/阻拦
if request.META.get('REMOTE_ADDR') not in allowed_ip:
return HttpResponse('您的IP地址无权访问')
else:
return None
def process_response(self, request, response):
return response
process_response 返回响应时执行;
默认情况下返回response, 即视图函数的返回值,如果在这个方法中自定义了返回值,将返回自定义返回值。
class CustomizeMiddleware(MiddlewareMixin):
def process_response(self, request, response):
print('处理一些逻辑条件等......')
return response
process_view 视图函数;
执行过程:
执行完process_request → 路由分发(dispatch) → process_view → 视图函数 → process_response
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse
class CustomizeMiddleware1(MiddlewareMixin):
def process_request(self,request):
print("...来自中间件1的请求...")
def process_response(self,request,response):
print("...来自中间件1的返回...")
return response
def process_view(self, request, callback, callback_args, callback_kwargs):
print("...中间件1view...")
class CustomizeMiddleware2(MiddlewareMixin):
def process_request(self,request):
print("...来自中间件2的请求...")
def process_response(self,request,response):
print("...来自中间件2的返回...")
return response
def process_view(self, request, callback, callback_args, callback_kwargs):
print("...中间件2view...")
class CustomizeMiddleware3(MiddlewareMixin):
def process_request(self,request):
print("...来自中间件3的请求...")
def process_response(self,request,response):
print("...来自中间件2的返回...")
return response
def process_view(self, request, callback, callback_args, callback_kwargs):
print("...中间件3view...")
输出结果为:
...来自中间件1的请求..
...来自中间件2的请求..
...来自中间件3的请求..
...中间件1view...
...中间件2view...
...中间件3view...
...来自中间件3的返回...
...来自中间件2的返回...
...来自中间件1的返回...
如图所示:
当最后一个中间的process_request到达路由关系映射之后,返回到中间件1的process_view,然后依次往下,到达views函数,最后通过process_response依次返回到达用户。
process_exception 视图中出现异常,就会被执行(默认不执行);
定义一个提示错误信息页面
from django.shortcuts import HttpResponse
class CustomizeMiddleware(MiddlewareMixin):
def process_exception(self, request, exception):
return HttpResponse('在处理中间件时,抛出了异常,就会走这里哦~')
process_template_response 若返回的对象有render方法,就会被执行(默认不执行);
process_template_response(self, request, response)
视图函数执行完成后立即执行
,但是它有一个前提条件,那就是视图函数返回的对象有一个render()方法
(或者表明该对象是一个TemplateResponse对象或等价方法)网站声明:如果转载,请联系本站管理员。否则一切后果自行承担。
添加我为好友,拉您入交流群!
请使用微信扫一扫!