首页IT科技django 中间表(django中间件以及自定义中间件)

django 中间表(django中间件以及自定义中间件)

时间2025-06-18 20:58:07分类IT科技浏览4218
导读:middleware 中间件就是在...

middleware

中间件就是在目标结果之间进行的额外处理过程             ,在Django中就是request和response之间进行的处理                    ,相对来说实现起来比较简单       ,但是要注意它是对全局有效的       ,可以在全局范围内改变输入和输出结果                    ,因此需要谨慎使用              ,否则不仅会造成难以定位的错误       ,而且可能会影响整体性能             。

中间件有什么用

如果想要修改HttpRequest或者HttpResponse                    ,就可以通过中间件来实现                    。

登陆认证:在中间件中加入登陆认证              ,所有请求就自动拥有登陆认证,如果需要放开部分路由                    ,只需要特殊处理就可以了       。 流量统计:可以针对一些渲染页面统计访问流量       。 恶意请求拦截:统计IP请求次数                     ,可以进行频次限制或者封禁IP                    。

本身django项目就带有很多的中间件,在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, ]

之前我们通过post请求发起的时候             ,就需要先注释掉csrf那一个中间件              。

每个中间件的功能如下,

SecurityMiddleware:为request/response提供了几种安全改进; SessionMiddleware:开启session会话支持; CommonMiddleware:基于APPEND_SLASH和PREPEND_WWW的设置来重写URL                     ,如果APPEND_SLASH设为True       ,并且初始URL 没有以斜线结尾以及在URLconf 中没找到对应定义             ,这时形成一个斜线结尾的新URL; CsrfViewMiddleware:添加跨站点请求伪造的保护                    ,通过向POST表单添加一个隐藏的表单字段       ,并检查请求中是否有正确的值; AuthenticationMiddleware:在视图函数执行前向每个接收到的user对象添加HttpRequest属性       ,表示当前登录的用户                    ,无它用不了request.user       。 MessageMiddleware:开启基于Cookie和会话的消息支持 XFrameOptionsMiddleware:对点击劫持的保护

除此以外, Django还提供了压缩网站内容的GZipMiddleware              ,根据用户请求语言返回不同内容的LocaleMiddleware和给GET请求附加条件的ConditionalGetMiddleware                    。这些中间件都是可选的              。

Django的中间件执行顺序

当你在settings.py注册中间件时一定要要考虑中间件的执行顺序       ,中间件在request到达view之前是从上向下执行的                    ,在view执行完后返回response过程中是从下向上执行的              ,如下图所示。举个例子,如果你自定义的中间件有依赖于request.user                    ,那么你自定义的中间件一定要放在AuthenticationMiddleware的后面

工作原理

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的输入或输出的改变是全局的                    ,反之亦然                     。如果让你希望对Django的输入或输出做出全局性的改变时              ,需要使用中间件       。举个例子,我们在装饰器一文中介绍了如何使用@login_required装饰器要求用户必须先登录才能访问我们的视图函数             。试想我们有个网站绝大部分视图函数都需要用户登录                    ,每个视图函数前面都需要加上@login_required装饰器是比较傻的行为                    。借助于中间件                     ,我们无需使用装饰器即可全局实现:只有登录用户才能访问视图函数,匿名用户跳转到登录页面       。实现原理也很简单             ,在一个request到达视图函数前                     ,我们先对request.user是否验证通过进行判断       ,然后再进行跳转       。另外Django对POST表单中携带的CSRF token的全局校验也是通过CsrfViewMiddleware这个中间件进行的             ,而不是通过单个装饰器实现的                    。

自定义中间件

一般的中间件必须要有的两个函数就是process_request和process_response

如果自己定义中间件                    ,首先在app里创建一个py文件       ,然后导入一些自带的模块

from django.utils.deprecation import MiddlewareMixin

然后就是自定义类

class ReginaMiddleWare(MiddlewareMixin): def process_request(self,request): :param request: 请求信息对象 :return: print("reginaMiddleWare",request) def process_response(self,response,request): :param response: 请求信息对象 :param request: 视图函数返回的响应体 :return: print(response) return response

第三步就是把自己写好的中间件按照目录位置添加到settings文件当中

MIDDLEWARE = [ django.middleware.clickjacking.XFrameOptionsMiddleware, reginauser.reginaMiddleware.ReginaMiddleWare, reginauser.reginaMiddleware.IvanleeMiddleWare ] reginaMiddleWare <WSGIRequest: GET /md/> ivanleeMiddleWare <WSGIRequest: GET /md/> <WSGIRequest: GET /md/> ivanleemiddleware <WSGIRequest: GET /md/> reginamiddleware <WSGIRequest: GET /md/>

process_request功能

ip = request.META.get("REMOTE_ADDR") if ip in [127.0.0.1,]: return HttpResponse("非法ip")

我们可以试一下本地地址       ,一旦process_request返回的不是默认的None                    ,则表示拦截成功              ,那么也不会经过IvanleeMiddleware       ,直接回到ReginaMiddleware的响应处原路返回

process_response

def process_response(self,response,request): :param response: 请求信息对象 :param request: 视图函数返回的响应体 :return: print("ivanleeMiddleWare_response") respnse = response.content + "<h1>I love Regina</h1>" return respnse

那么在返回的时候                    ,响应内容就是原有的helloworld和IloveRegina一起发送给请求者              。

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
网站排名怎么做上去(网站排名快速见效的方法) create repository(createrepo命令 – 创建软件仓库及生成元数据)