深入理解Django的中间件middleware

本文讲述的内容基于 Django 1.11

摘要

Django 中的中间件(middleware),是一个镶嵌到Django的request/response处理机制中的一个hooks框架,是一个修改django全局输入输出的一个底层插件系统。让我们可以自定义想要的一些功能来处理用户的请求。

在Django中,中间件其实就是一个类,在类中包含一组特定的功能,在请求到来或者结束时,Django会根据我们定义的中间件规则执行中间件中对应的方法,一个 Django 项目默认激活的中间件在我们项目中的配置中可以看到是这个样子的:

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',
]

MIDDLEWARE这里列表中的每一个元素,其实就是一个个单独的中间件,举例来说:django.middleware.csrf.CsrfViewMiddleware这个中间件,作用就是在我们的 form 表单提交请求的时候,提交的时候必须要带上csrf_token,否则就不会正确提交。

中间件使用也需要讲究顺序,下一层依赖上一层的封装,例如,我们的AuthenticationMiddleware是一个认证中间件,在session 中保存认证用户的信息,但是他必须依赖于SessionMiddleware才可以被正确使用,所以他也必须在SessionMiddleware之后。但是具体的顺序问题可以参考这里

中间件结构

中间件类中需要包含以下处理方法:

1. process_request(self, request)
2. process_view(self, request, callback, callback_args, callback_kwargs)
3. process_template_response(self, request, response)
4. process_exception(self, request, exception)
5. process_response(self, request, response)

执行过程

以我们的项目中默认中间件为例子,具体的流程如下所示:

中间件执行前提

中间件要按照一定的顺序一层一层的执行下去,需要按照标准返回特定的内容:

  • 如果为 None,则按照顺序继续向下执行
  • 如果为 HttpResonse 对象,则直接将这个对象返回给用户

此处有一个版本前后的区别,请大家注意区分:

在 Django1.10之后, 当某个中间件,例如CsrfViewMiddleware请求process_request没有返回 None 后,这个请求会交给CsrfViewMiddleware的process_response来返回,即返回给相同一层的中间件来返回:

在 Django1.10之前的版本,会返回到最底层的中间件来返回:

中间件方法:

1、process_request(self, request)

其中request参数就是我们的HttpRequest对象,process_request 会在每个request在被决定使用哪个view之前调用,它会返回None或HttpResponse对象

2、process_view(self, request, callback, callback_args, callback_kwargs)

其中request参数就是的HttpRequest对象,callback 就是请求被决定使用的 view 函数,书具体的函数名,不是字符串类型。callback_args和callback_kwargs是 view 函数需要接受的参数,它会返回None或HttpResponse对象

3、process_template_response(self, request, response)

其中request 是 HttpRequest 对象, response 是一个由Django view或者中间件返回的TemplateResponse 对象,process_template_response()在 view 使用 render 渲染一个模版对象完成之后被调用,它必须返回一个render 方法执行后的response对象。

4、process_exception(self, request, exception)

其中request参数就是的HttpRequest对象,exception是view函数中raise的Exception对象,当 view 函数 raise 一个 exception 的时候调用process_exception,它会返回None或HttpResponse对象

5、process_response(self, request, response)

其中request是 HttpRequest 对象,response 是一个django view或者中间件返回的 HttpResponse 或者StreamingHttpResponse对象,process_response会在所有响应到达浏览器之前被调用

中间件的详细执行流程

由于process_template_response在特定的 rander 渲染中才会被调用,所以过程中不添加该方法

自建中间件与执行过程测试

为了更加清晰的展示中间件的执行过程与如何自定义一个中间件,我们模拟一个简单的用户请求和中间件执行过程:

自定义中间件

from django.utils.deprecation import MiddlewareMixin
class MyMiddleware_1(MiddlewareMixin):
 def process_request(self, request):
  print("自定义 process_request 1")
  return None

 def process_response(self, request, response):
  print("自定义 process_response 1")
  return response

 def process_view(self, request, callback, callback_args, callback_kwargs):
  print("自定义 process_view 1")
  return None

 def process_exception(self, request, exception):
  print("自定义 process_exception 1")

class MyMiddleware_2(MiddlewareMixin):

 def process_request(self, request):
  print("自定义 process_request 2")
  return None

 def process_response(self, request, response):
  print("自定义 process_response 2")
  return response

 def process_view(self, request, callback, callback_args, callback_kwargs):
  print("自定义 process_view 2")
  return None

 def process_exception(self, request, exception):
  print("自定义 process_exception 2")

引入

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',
 'app01.middle_by_me.MyMiddleware_1', # 第一个自定义 middleware
 'app01.middle_by_me.MyMiddleware_2' # 第二个自定义 middleware
]

输出结果

自定义中间件应用场景

应用场景这个问题其实不是很好去固定,因为大家在实际使用过程中的需求都不尽相同,所以我简单的举个我可以想到的例子吧。

在不修改业务逻辑源代码的情况下,我可以使用中间件来对用户的访问进行一定的筛选过滤,或者访问控制。还有能想到的更加牛逼的操作是当源站的 CDN,请求穿透源站,middleware 判断请求的内容是否在缓存中,如果在缓存直接返回,而可以不经过业务后端逻辑,是不是很骚~

是不是很像一个所有视图函数的装饰器~~

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我们的支持。

您可能感兴趣的文章:

  • 简介Django中内置的一些中间件
  • 详解Python的Django框架中的中间件
  • Django中间件工作流程及写法实例代码
(0)

相关推荐

  • Django中间件工作流程及写法实例代码

    熟悉web开发的同学对hook钩子肯定不陌生,通过钩子可以方便的实现一些触发和回调,并且做一些过滤和拦截. django中的中间件(middleware)就是类似钩子的一种存在.下面我们来介绍一下,并且给出一些实例. 1.Middleware的工作流程 我盗了一个图,看网上很多人用这个图,来源已经追不明白了.简单声明一下,这个图不是我的.看着图我们分析一下: 1)django的请求相应流程:HttpRequest -> RequestMiddleware -> view function -&

  • 简介Django中内置的一些中间件

    认证支持中间件 中间件类: django.contrib.auth.middleware.AuthenticationMiddleware . django.contrib.auth.middleware.AuthenticationMiddleware . 这个中间件激活认证支持功能. 它在每个传入的 HttpRequest 对象中添加代表当前登录用户的 request.user 属性. It adds the request.user attribute, representing the

  • 详解Python的Django框架中的中间件

    什么是中间件 我们从一个简单的例子开始. 高流量的站点通常需要将Django部署在负载平衡proxy之后. 这种方式将带来一些复杂性,其一就是每个request中的远程IP地址(request.META["REMOTE_IP"])将指向该负载平衡proxy,而不是发起这个request的实际IP. 负载平衡proxy处理这个问题的方法在特殊的 X-Forwarded-For 中设置实际发起请求的IP. 因此,需要一个小小的中间件来确保运行在proxy之后的站点也能够在 request.

  • 深入理解Django的中间件middleware

    本文讲述的内容基于 Django 1.11 摘要 Django 中的中间件(middleware),是一个镶嵌到Django的request/response处理机制中的一个hooks框架,是一个修改django全局输入输出的一个底层插件系统.让我们可以自定义想要的一些功能来处理用户的请求. 在Django中,中间件其实就是一个类,在类中包含一组特定的功能,在请求到来或者结束时,Django会根据我们定义的中间件规则执行中间件中对应的方法,一个 Django 项目默认激活的中间件在我们项目中的配

  • Django框架中间件(Middleware)用法实例分析

    本文实例讲述了Django框架中间件(Middleware)用法.分享给大家供大家参考,具体如下: 1.面向切面编程 切点(钩子) 切点允许我们动态的在原有逻辑中插入一部分代码 在不修改原有代码的情况下,动态注入一部分代码 默认情况,不中断传播,切点会自动愈合(自动执行原有逻辑) 如果我们执行了中断操作(return,raise),没接上,会直接到程序结尾 五个切面:1.请求交给路由处理之前:2.请求交给视图处理之前:3.请求交给视图渲染后:4.渲染结果返回给模板之前:5.出现异常. 2.Dja

  • Django教程笔记之中间件middleware详解

    中间件介绍 中间件顾名思义,是介于request与response处理之间的一道处理过程,相对比较轻量级,并且在全局上改变django的输入与输出.因为改变的是全局,所以需要谨慎实用,用不好会影响到性能. 每个中间件都会负责一个功能,例如,AuthenticationMiddleware,与sessions处理相关. 激活中间件 需要在settings.py配置文件中,配置MIDDLEWARE_CLASSES: MIDDLEWARE_CLASSES = [ 'django.middleware.

  • Django框架教程之中间件MiddleWare浅析

    前言 Django中的中间件是一个轻量级.底层的插件系统,可以介入Django的请求和响应处理过程,修改Django的输入或输出. 中间件的设计为开发者提供了一种无侵入式的开发方式,增强了Django框架的健壮性. 我们可以使用中间件,在Django处理视图的不同阶段对输入或输出进行干预. 中间件的原理其实就是定义了一个装饰器,但是这个装饰器可以对整个项目中的所有方法进行装饰: 我们可以通过中间件,对请求对象和响应对象进行相应的干预操作. 实现中间件的流程: 1.在子应用中编写一个middlew

  • Django框架之中间件MiddleWare的实现

    Django中的中间件是一个轻量级.底层的插件系统,可以介入Django的请求和响应处理过程,修改Django的输入或输出. 中间件的设计为开发者提供了一种无侵入式的开发方式,增强了Django框架的健壮性. 我们可以使用中间件,在Django处理视图的不同阶段对输入或输出进行干预. 中间件的原理其实就是定义了一个装饰器,但是这个装饰器可以对整个项目中的所有方法进行装饰: 我们可以通过中间件,对请求对象和响应对象进行相应的干预操作. 实现中间件的流程: 1.在子应用中编写一个middleware

  • 理解ASP.NET Core 中间件(Middleware)

    目录 中间件 中间件管道 Run Use UseWhen Map MapWhen Run & Use & UseWhen & Map & Map 编写中间件并激活 基于约定的中间件 基于工厂的中间件 基于约定的中间件 VS 基于工厂的中间件 中间件 先借用微软官方文档的一张图: 可以看到,中间件实际上是一种配置在HTTP请求管道中,用来处理请求和响应的组件.它可以: 决定是否将请求传递到管道中的下一个中间件 可以在管道中的下一个中间件处理之前和之后进行操作 此外,中间件的注

  • django框架中间件原理与用法详解

    本文实例讲述了django框架中间件原理与用法.分享给大家供大家参考,具体如下: 中间件:轻量级,介于 request和response之间的一道处理过程,在全局上改变了输入和输出 在django中就默认使用了七个中间件 MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.

  • Django使用中间件解决前后端同源策略问题

    问题描述 前端时间在公司的时候,要使用angular开发一个网站,因为angular很适合前后端分离,所以就做了一个简单的图书管理系统来模拟前后端分离. 但是在开发过程中遇见了同源策略的跨域问题,页面能够显示,但是却没有数据,显示如下 右键检查报错如下: 报错代码如下 Failed to load http://127.0.0.1:8888/publisher/: No 'Access-Control-Allow-Origin' header is present on the requeste

  • 详解django自定义中间件处理

    中间件是一个钩子框架,它们可以介入 Django 的请求和响应处理过程. 它是一个轻量级.底层的 插件 系统,用于在 全局修改 Django 的输入或输出 . 每个中间件组件负责完成某个特定的功能 这里介绍的中间件方法适用于 Django1.10 以上 相关文件: django middleware Django基础中间件 django.utils.deprecation.py class MiddlewareMixin(object): def __init__(self, get_respo

  • 深入理解 Koa 框架中间件原理

    Node 主要用在开发 Web 应用,koa 是目前 node 里最流行的 web 框架. 在 Node 开启一个 http 服务简直易如反掌,官网 demo. const http = require("http"); const server = http.createServer((req, res) => { res.statusCode = 200; res.setHeader("Content-Type", "text/plain&quo

随机推荐