当前位置:   article > 正文

django---中间件_django中间件

django中间件

django中间件

介绍

官方介绍:

中间件是一个钩子框架,它们可以介入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数据进行修改后返回给用户

图解

django请求流程图

2.django的七个内置中间价

介绍

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

注意Django的中间件执行顺序

1. MIDDLEWARE中的顺序很重要,因为中间件可以依赖于其他中间件
2. 当你在settings.py注册中间件时一定要要考虑中间件的执行顺序,在请求阶段,在调用视图之前,Django以MIDDLEWARE(自上而下)定义的顺序应用中间件

3. 在处理响应期间,中间件的执行顺序是从下往上的

4. 如果你自定义的中间件有依赖于request.user(比如判断用户是否登录),那么你自定义的中间件一定要放在AuthenticationMiddleware的后面。

3. 如何自定义中间件

介绍

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

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

使用(django3.x以下)

介绍

  • 1.在项目名或者应用名下创建一个任意名称的文件夹
  • 2.在该文件夹内创建一个任意名称的py文件
  • 3.在该py文件内需要书写类(这个类必须继承MiddlewareMixin),然后在这个类里面就可以自定义五个方法了,(这五个方法并不是全部都需要书写,用几个写几个)
  • 4.需要将类的路径以字符串的形式注册到配置文件中才能生效

Middleware.py

  1. from django.utils.deprecation import MiddlewareMixin
  2. from django.http import HttpResponse
  3. from django.shortcuts import HttpResponse, redirect
  4. class MyMiddleware(MiddlewareMixin):
  5. def process_request(self, request):
  6. next_url = request.path_info
  7. if not request.path_info.startswith("/login/"):
  8. # 做登录验证
  9. login_flag = request.session.get("login", "")
  10. if not login_flag:
  11. return redirect("/login/?next={}".format(next_url))
  12. def process_view(self, request, view_func, view_args, view_kwargs):
  13. pass
  14. def process_exception(self, request, exception):
  15. if isinstance(exception, ValueError):
  16. return HttpResponse("404")
  17. def process_response(self, request, response):
  18. return response

settings.py

  1. MIDDLEWARE = [
  2. ...
  3. 'mymiddlewares.middlewares.MyMiddleware',
  4. ]

使用(django3.x以上)

Middleware.py

  1. class MyFirstMiddleware:
  2. def __init__(self, get_response):
  3. self.get_response = get_response
  4. # One-time configuration and initialization.一次性设置和初始化
  5. def __call__(self, request):
  6. # Code to be executed for each request before
  7. # the view (and later middleware) are called.
  8. print("接收到request请求,视图函数马上执行")
  9. if not request.user.is_authenticated:
  10. print("该请求用户尚未登录")
  11. response = self.get_response(request)
  12. # Code to be executed for each request/response after
  13. # the view is called. 视图函数执行后的代码
  14. print("视图函数执行结束,准备提供响应")
  15. return response
  16. def process_view(self, request, view_func, view_args, view_kwargs):
  17. pass
  18. def process_exception(self, request, exception):
  19. pass
  20. def process_template_response(self, request, response):
  21. pass

settings.py

因为我们自定义的中间件依赖于request对象,我们一定要放在AuthenticationMiddleware的后面

  1. MIDDLEWARE = [
  2. ...
  3. 'django.contrib.auth.middleware.AuthenticationMiddleware',
  4. 'django.contrib.messages.middleware.MessageMiddleware',
  5. 'django.middleware.clickjacking.XFrameOptionsMiddleware',
  6. 'users.middleware.MyFirstMiddleware',
  7. ]

案例三

Middleware.py

  1. MyDjango/myMiddleware.py:
  2. from django.utils.deprecation import MiddlewareMixin
  3. class MyMiddleware(MiddlewareMixin):
  4. def __init__(self, get_response=None):
  5. """运行Django将自动执行"""
  6. super().__init__(get_response)
  7. self.get_response = get_response
  8. print('This is __init__')
  9. def process_request(self, request):
  10. """生成请求对象后,路由匹配之前"""
  11. print('This is process_request')
  12. def process_view(self, request, func, args, kwargs):
  13. """路由匹配后,视图函数调用之前"""
  14. print('This is process_view')
  15. def process_exception(self, request, exception):
  16. """视图函数发生异常时"""
  17. print('This is process_exception')
  18. def process_response(self, request, response):
  19. """视图函数执行后,响应内容返回浏览器之前"""
  20. print('This is process_response')
  21. return response

settings.py

  1. MIDDLEWARE = [
  2. ...
  3. 'MyDjango.myMiddleware.MyMiddleware'
  4. ]

参考文章

(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)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/71719?site
推荐阅读
相关标签
  

闽ICP备14008679号