中间件是Django请求/响应处理的钩子框架。它是一个轻量级的、低级的"插件"系统,用于全局改变Django的输入或输出。
中间件的设计为开发者提供了一种无侵入式的开发方式,增强了Django框架的健壮性。
我们可以使用中间件,在Django处理视图的不同阶段对输入或输出进行干预。
自定义中间件有2种方法
定义一个中间件函数,然后返回一个可以被调用的中间件。
中间件函数需要接受一个可以调用的get_response对象。
返回的中间件也是一个可以被调用的对象,并且像视图一样需要接收一个request对象参数,返回一个response对象。
def simple_middleware(get_response):
# TODO 此处编写的代码仅在Django第一次配置和初始化的时候执行一次。
def middleware(request):
# TODO 此处编写的代码会在每个请求处理视图前被调用。
response = get_response(reqeust)
# TODO 此处编写的代码会在每个请求处理视图之后被调用。
return response
return middleware
定义一个中间件类,需要实现__init__方法和__call__方法,需要初始化Django提供的get_response方法,接收request对象,返回一个response对象。可以是一个真实的视图,也可能是请求处理链中的下一个中间件。
class SimpleMiddleware:
def __init__(self, get_response)
self.get_response = get_response
# TODO 此处编写的代码仅在Django第一次配置和初始化的时候执行一次。
def __call__(self, request)
# TODO 此处编写的代码会在每个请求处理视图前被调用。
response = self.get_response(request)
# TODO 此处编写的代码会在每个请求处理视图之后被调用。
return response
Django实现了一个Middleware装饰器,在django.utils.deprecation.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
用类实现中间件时,只需要继承MiddlewareMixin
,然后实现process_request
和process_response
方法。
class MyMiddleware(MiddlewareMixin):
def __init__(get_response):
super(MyMiddleware, self).__init__(get_response)
print('初始化执行且执行一次')
def process_request(self, request):
print('视图函数处理之前执行')
def process_response(self, request, response):
print('视图函数处理之后执行')
return response
例如:在apps应用中新建一个middleware.py
文件:
def my_middleware(get_response):
print('只在初始化时执行一次。。。')
def middleware(request):
print('before request 时被调用。。。')
response = get_response(request)
print('after request 时被调用。。。')
return response
retrun middleware
定义好中间件后,需要在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',
'apps.middleware.my_middleware', # 添加中间件
]
定义一个视图进行测试
def demo_view(request):
print('view 视图被调用')
return HttpResponse('ok')
执行结果
注意:Django运行在调试模式下,中间件init部分有可能被调用两次。
例如:
定义两个中间件
def my_middleware(get_response):
print('init 被调用')
def middleware(request):
print('before request 被调用')
response = get_response(request)
print('after response 被调用')
return response
return middleware
def my_middleware2(get_response):
print('init2 被调用')
def middleware(request):
print('before request 2 被调用')
response = get_response(request)
print('after response 2 被调用')
return response
return middleware
注册添加两个中间件
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',
'users.middleware.my_middleware', # 添加
'users.middleware.my_middleware2', # 添加
]
执行结果
init2 被调用
init 被调用
before request 被调用
before request 2 被调用
view 视图被调用
after response 2 被调用
after response 被调用
基于Nginx+Supervisord+uWSGI+Django1.11.1+Python3.6.5构建