1.定义
中间件:介于 request 与 response 处理之间,并且在全局上改变 django 的输入与输出的一道处理过程.
特点:轻量级,且需要谨慎实用,用不好会影响到性能
Django 默认的中间件:
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',
]
2.中间件的实现流程
注意:
1.先process_request,process_view(md1,md2)
2.然后process_exception,process_template_response,process_response(md2,md1)
3.自定义中间件
1.Django1.x,2.x自定义中间件
1.四个方法
方法名 |
---|
process_request(self,request) |
process_view(self, request, callback, callback_args, callback_kwargs) |
process_exception(self, request, exception) |
process_template_response(self,request,response) |
process_response(self,request,response) |
2.代码实现
setting.py
my_middle.py
from django.utils.deprecation import MiddlewareMixin
class Md1(MiddlewareMixin):
def process_request(self, request):
print("Md1请求")
def process_view(self, request, callback, callback_args, callback_kwargs):
print("md1 process_view...")
def process_exception(self, request, exception):
print("md1 process_exception...")
def process_response(self, request, response):
print("Md1返回")
return response
class Md2(MiddlewareMixin):
def process_request(self, request):
print("Md2请求")
def process_view(self, request, callback, callback_args, callback_kwargs):
print("md2 process_view...")
def process_exception(self, request, exception):
print("md2 process_exception...")
def process_response(self, request, response):
print("Md2返回")
return response
views.py
def index(request):
print("view函数...")
return HttpResponse("OK")
结果:
Md1请求
Md2请求
md1 process_view...
md2 process_view...
Md2返回
Md1返回
注意:
process_request添加HttpResponse(“中断”)
- Md1中process_request()直接return HttpResponse(“中断”),结果如下
Md1请求
Md1返回
- Md2中process_request()直接return HttpResponse(“中断”),结果如下
Md1请求
Md2请求
Md2返回
Md1返回
process_view添加HttpResponse(“中断”)
- 当Md1的process_view直接return HttpResponse(“中断”)
Md1请求
Md2请求
md1 process_view...
Md2返回
Md1返回
- 当Md1的process_view直接return HttpResponse(“中断”)
Md1请求
Md2请求
md1 process_view...
md2 process_view...
Md2返回
Md1返回
process_exception添加HttpResponse(exception)
- 将 Md1 的 process_exception添加return HttpResponse(exception) 返回结果如下:
Md1请求
Md2请求
md1 process_view...
md2 process_view...
md2 process_exception...
md1 process_exception...
Md2返回
Md1返回
- 将 Md2 的 process_exception添加return HttpResponse(exception) 返回结果如下:
Md1请求
Md2请求
md1 process_view...
md2 process_view...
md2 process_exception...
Md2返回
Md1返回
2.Django 3.0自定义中间件
1.函数实现方式
def simple_middleware(get_response):
# 此处编写的代码仅在Django第一次配置和初始化的时候执行一次。
def middleware(request):
# 此处编写的代码会在每个请求处理视图前被调用。
response = get_response(request)
# 此处编写的代码会在每个请求处理视图之后被调用。
return response
return middleware
2.类实现方式
class SimpleMiddleware:
def __init__(self, get_response):
self.get_response = get_response
# One-time configuration and initialization.一次性设置和初始化
def __call__(self, request):
# Code to be executed for each request before
# the view (and later middleware) are called.
# 视图函数执行前的代码
response = self.get_response(request)
# Code to be executed for each request/response after
# the view is called. 视图函数执行后的代码
return response
3.代码示例
setting.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',
"rbac.middlewares.rbac.my_middleware",
"rbac.middlewares.rbac.MyFirstMiddleware",
]
app:middleware.py
def my_middleware(get_response):
print('init 被调用')
def middleware(request):
print('before request 被调用')
response = get_response(request)
print('after response 被调用')
return response
return middleware
class MyFirstMiddleware:
def __init__(self, get_response):
self.get_response = get_response
print('init2 被调用')
def __call__(self, request):
print('before request 2 被调用')
response = self.get_response(request)
print('after response 2 被调用')
return response
执行结果
init2 被调用
init 被调用
before request 被调用
before request 2 被调用
after response 2 被调用
after response 被调用
注意:
1.init只在项目初始化时调用一次
2.init>request>response
3.request是由上往下
4.init,response顺序皆是下往上
4.应用案例
1.做IP访问频率限制
某些 IP 访问服务器的频率过高,进行拦截,比如限制每分钟不能超过 20 次。
2.URL访问过滤
如果用户访问的是 login 视图(放过)
如果访问其他视图,需要检测是不是有 session 认证,已经有了放行,没有返回 login,这样就省得在多个视图函数上写装饰器了
setting.py
WHITE_LIST = ["/", "/my_model/login", "/my_model/reg", "/my_model/logout"]
my_middle.py
class MyMiddle1(MiddlewareMixin):
def process_request(self, request):
print("MyMiddle1 process_request ... ")
if request.path in WHITE_LIST:
return None
if request.user.is_authenticated:
return redirect("/my_model/login")