官方介绍:
中间件是一个钩子框架,它们可以介入Django 的请求和响应处理过程。 它是一个轻量级、底层的“插件”系统,用于在全局修改Django 的输入或输出。
介绍1:
首先django自带七个中间件,
每个中间件都有各自对应的功能
并且django还支持程序员自定义中间件
在用django开发项目的时候 只要设计到全局相关的功能都可以使用中间件方便的完成
- 全局用户身份校验
- 全局用户权限校验
- 全局访问频率校验
介绍2:
HTTP Web服务器工作原理一般都是接收用户发来的请求(request), 然后给出响应(response)。
Django也不例外,其一般工作方式是接收request对象和其它参数,交由视图(view)处理,然后给出它的响应(respone)数据: 渲染过的html文件或json格式的数据。
然而在实际工作中Django并不是接收到request对象后,马上交给视图函数或类(view)处理,也不是在view执行后立马给用户返回reponse。
事实上Django最初接收的是HttpRequest对象,而不是request对象,正是中间件的作用把HttpRequest对象和user对象打包成了一个全局变量request对象,这样你才可以View中使用request作为变量或者在模板中随意调用request.user。
中间件(Middleware)在整个Django的request/response处理机制中的角色如下所示:
HttpRequest -> Middleware -> View -> Middleware -> HttpResponse
正是由于一个请求HttpRequest在传递给视图View处理前要经过中间件处理,经过View处理后的响应也要经过中间件处理才能返回给用户,我们可以编写自己的中间件实现权限校验,限制用户请求、打印日志、改变输出内容等多种应用场景,比如:
禁止特定IP地址的用户或未登录的用户访问我们的View视图函数
对同一IP地址单位时间内发送的请求数量做出限制
在View视图函数执行前记录用户的IP地址
在View视图函数执行前传递额外的变量或参数
在View视图函数执行前或执行后把特定信息打印到log日志
在View视图函数执行后对reponse数据进行修改后返回给用户
MIDDLEWARE = [
# 为请求/响应循环提供了几种安全改进
'django.middleware.security.SecurityMiddleware',# 开启会话支持
'django.contrib.sessions.middleware.SessionMiddleware',# 基于APPEND_SLASH和PREPEND_WWW的设置来重写URL
# 如果APPEND_SLASH设为True,并且初始URL 没有以斜线结尾以及在URLconf 中没找到对应定义,这时形成一个斜线结尾的新URL
'django.middleware.common.CommonMiddleware',# 添加跨站点请求伪造的保护,通过向POST表单添加一个隐藏的表单字段,并检查请求中是否有正确的值
'django.middleware.csrf.CsrfViewMiddleware',# 向每个接收到的user对象添加HttpRequest属性,表示当前登录的用户
'django.contrib.auth.middleware.AuthenticationMiddleware',# 开启基于Cookie和会话的消息支持
'django.contrib.messages.middleware.MessageMiddleware',# 对点击劫持的保护
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
1. 如果你要实现全站缓存, 还需要使用UpdateCacheMiddleware和FetchFromCacheMiddleware,但一定要注意它们的顺序,Update在前和Fetch在后。
MIDDLEWARE = [
'django.middleware.cache.UpdateCacheMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.cache.FetchFromCacheMiddleware',
]
2.压缩网站内容的:GZipMiddleware,
根据用户请求语言返回不同内容:LocaleMiddleware
给GET请求附加条件:ConditionalGetMiddleware
1. MIDDLEWARE中的顺序很重要,因为中间件可以依赖于其他中间件
2. 当你在settings.py注册中间件时一定要要考虑中间件的执行顺序,在请求阶段,在调用视图之前,Django以MIDDLEWARE(自上而下)定义的顺序应用中间件3. 在处理响应期间,中间件的执行顺序是从下往上的
4. 如果你自定义的中间件有依赖于request.user(比如判断用户是否登录),那么你自定义的中间件一定要放在AuthenticationMiddleware的后面。
1. 中间件类必须实现下列五个方法中的一个或多个
process_request(self,request):
作用:执行主路由之前被掉用,请求来的时候,需要经过每一个中间件里面的process_request方法 结果的顺序是按照,配置文件中注册的,中间件从上往下的顺序依次执行,如果中间件里面没有定义该方法,那么直接跳过执行下一个中间件返回None:请求通过,交给下一个中间价处理
返回HttpResponse对象:请求不通过,由当前中间价的,process_response直接往上一层层的返回
用途:过滤请求
process_view(self,request,callback,callback_args,callback_kwargs):
作用:callback:为视图函数;
callback_args:视图函数的位置参数,
callback_kwargs:视图函数的关键字参数;调用视图之前被调用,在每个请求上调用
返回None:请求通过,交给下一个中间价处理
返回HttpResponse对象:请求不通过,由当前中间价的process_response直接往上一层层的返回
用途:用于代码层面的替换和过滤,这个方法可以拿到视图函数的参数
process_response(self,request,response):
作用:response:是视图函数的响应对象;在响应返回浏览器之前被调用(完成视图的执行但还未把它返回给浏览器),在每个请求上走的时候,需要经过每一个中间件里面的process_response方法,顺序是按照配置文件中注册了的中间件从下往上依次经过,如果没有定义的话 直接跳过执行下一个
参数:该方法有两个额外的参数request,response
返回:该方法必须返回一个HttpResponse对象
1.默认返回的就是形参response
2.也可以自己返回自己的
注意:如果返回HttpResponse,会替换response,与process_request不同的是,会继续往上走,其上面的中间件拿到的response,都是被替换的HttpResponse
process_exception(self,request,exception):
作用:在执行视图时,发生的异常时被调用,返回一个HttpResponse对象
用途:用于一般用于捕获发生的异常,并将其邮件发送给开发人员
process_template_response(self,request,response):
作用:在视图函数执行完毕,且视图函数返回的对象中,包含render方法时被调用;该方法需要返回实现了render方法的响应对象
__init__(get_response)
:
- 必须配置get_response
flask框架也会有一个中间件 但是他的规律 只要返回数据了就必须经过所有中间件,里面的类似于process_response方法
注意:中间件中的大多数方法在返回None时表示忽略当前操作进入下一项事件,当返回HttpResponse对象时,表示此请求结束,直接返回给客户端
HttpResponse_骑台风走的博客-CSDN博客username = request.session.get('name', '游客')session:所有的数据存储在服务端,在客户端用cookie存储session_id。request.session.set_expiry(10) 设置为10秒后过期。# request.session.clear() # 方法2。request.session.flush() # 方法3。logout(request) # 方法1,推荐。http协议是无状态的,每次请求都是一次新的请求,它不记得之前的请求。https://blog.csdn.net/qq_52385631/article/details/126942861?spm=1001.2014.3001.5501
- 1.在项目名或者应用名下创建一个任意名称的文件夹
- 2.在该文件夹内创建一个任意名称的py文件
- 3.在该py文件内需要书写类(这个类必须继承MiddlewareMixin),然后在这个类里面就可以自定义五个方法了,(这五个方法并不是全部都需要书写,用几个写几个)
- 4.需要将类的路径以字符串的形式注册到配置文件中才能生效
from django.utils.deprecation import MiddlewareMixin
from django.http import HttpResponse
from django.shortcuts import HttpResponse, redirect
class MyMiddleware(MiddlewareMixin):
def process_request(self, request):
next_url = request.path_info
if not request.path_info.startswith("/login/"):
# 做登录验证
login_flag = request.session.get("login", "")
if not login_flag:
return redirect("/login/?next={}".format(next_url))
def process_view(self, request, view_func, view_args, view_kwargs):
pass
def process_exception(self, request, exception):
if isinstance(exception, ValueError):
return HttpResponse("404")
def process_response(self, request, response):
return response
MIDDLEWARE = [
...
'mymiddlewares.middlewares.MyMiddleware',
]
class MyFirstMiddleware:
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.
print("接收到request请求,视图函数马上执行")
if not request.user.is_authenticated:
print("该请求用户尚未登录")
response = self.get_response(request)
# Code to be executed for each request/response after
# the view is called. 视图函数执行后的代码
print("视图函数执行结束,准备提供响应")
return response
def process_view(self, request, view_func, view_args, view_kwargs):
pass
def process_exception(self, request, exception):
pass
def process_template_response(self, request, response):
pass
因为我们自定义的中间件依赖于request对象,我们一定要放在AuthenticationMiddleware的后面
MIDDLEWARE = [
...
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'users.middleware.MyFirstMiddleware',
]
MyDjango/myMiddleware.py:
from django.utils.deprecation import MiddlewareMixin
class MyMiddleware(MiddlewareMixin):
def __init__(self, get_response=None):
"""运行Django将自动执行"""
super().__init__(get_response)
self.get_response = get_response
print('This is __init__')
def process_request(self, request):
"""生成请求对象后,路由匹配之前"""
print('This is process_request')
def process_view(self, request, func, args, kwargs):
"""路由匹配后,视图函数调用之前"""
print('This is process_view')
def process_exception(self, request, exception):
"""视图函数发生异常时"""
print('This is process_exception')
def process_response(self, request, response):
"""视图函数执行后,响应内容返回浏览器之前"""
print('This is process_response')
return response
MIDDLEWARE = [
...
'MyDjango.myMiddleware.MyMiddleware'
]
(13条消息) Django学习(三):中间件_Lee-hua的博客-CSDN博客_django中间件
django HttpResponse对象 - 超级学渣渣 - 博客园 (cnblogs.com)
(13条消息) Django:中间件_dongys_z的博客-CSDN博客
(13条消息) Django—中间件详解_最萌毕加索的博客-CSDN博客_django中间件
(13条消息) django:中间件_dangfulin的博客-CSDN博客_django的中间件
Django基础(33): 中间件(middleware)的工作原理和应用场景举例 (qq.com)