1. 定义

中间件是一个钩子框架,深入到django的请求/响应处理过程中。这是一个轻量、底层插件系统,目的是全局修改django的输入或输出。每一个中间件组件都是用来处理特定的功能。例如django中间件组件:AuthenticationMiddleware用来关联请求用户,采用的方式是使用session。

2. 原理

中间件工厂是一个可调用对象,接收get_response作为参数,并返回一个中间件,返回的中间件也是一个可调用对象,接收一个request,并返回一个response,向一个view函数,中间件工厂其实很像装饰器。具体实现方式有:函数方式(像使用函数实现的装饰器)、类方式(像使用类实现的装饰器)。示例代码如下:

def simple_middleware(get_response):
# 这里添加代码:一次性配置和初始化
def middleware(request):
# 这里添加代码:在view、下一个中间件执行之前执行的代码
response = get_response(request)
# 这里添加代码:view调用之后,为每一个请求/响应代码
return response
return middleware class SimpleMiddleware(object):
def __init__(self, get_response):
self.get_response = get_response
# 这里添加代码:一次性配置和初始化 def __call__(self, request):
# 这里添加代码:在view、下一个中间件执行之前执行的代码
response = get_response(request)
# 这里添加代码:view调用之后,为每一个请求/响应代码
return response

get_response可调用对象是由django提供的:可能是一个真实的view函数(如果是最后列出的中间件)、或者中间件链中的下一个中间件。当前中间件不需要知道或者关心get_response是什么,只要明白它将呈现下一步内容。

3. 存放路径

中间件是存放在一个Python文件中,可能放在任意Python搜索文件方式的路径中,只要能够在MIDDLEWARE变量中找到即可。

MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

4. 解析步骤

根据请求阶段,在调用view函数之前,django按照定义在MIDDLEWARE中的顺序,从上往下应用中间件。请求是从上往下一层一层往下传递get_response,直到核心(view),响应则是返回来的顺序(由核心开始)。如果某一层决定短路并返回一个响应,而没有调用它的get_repsonse,那么在内部的层(包括view函数)都将被看不到请求和响应。

顺序:__call__: 前部分 --> self.get_response(request) --> 后部分

self.get_response(request)内部顺序:process_view() -> view函数

多个中间件:同名函数先执行,比如:(中间件A的__call__前部分 --> 中间件B的前部分)前部分 --> (中间件A的process_view --> 中间件B的process_view)self.get_response(request) --> (中间件B的__call__后部分 --> 中间件A的后部分)后部分

5. 中间件钩子

出了前面描述的基本请求响应中间件模式,你可以添加另外三个特殊的方法(基于类的中间件),另外还有两个函数是旧式风格(MIDDLEWARE_CLASSES):

5.1. process_view():

process_view(request, view_func, view_args, view_kwargs)

  • request:请求对象,view_func:函数对象,view_args: view的位置参数,view_kwargs: view的关键字参数,view_args和view_kwargs都不包含request对象(第一个view参数)
  • 在django调用view之前调用该函数
  • 返回None(将继续处理请求,执行其他中间件提供的process_view函数,并且核心的view函数)、或者HttpResponse对象(将不再调用下面的流程,将返回结果到前端)

5.2. process_exception():

process_exception(request, exception)

  • request:请求对象,exception: view函数抛出的一次对象
  • 当一个view抛出了异常后,将调用该函数
  • 返回None(默认异常处理流程)、或者HttpResponse对象(模板响应、中间件响应将被应用上、并且响应结果返回给浏览器)

5.3. process_template_response():

process_template_response(request, response)

  • request: 请求对象,response: 由view或者中间件返回的TemplateResponse对象
  • 在view完成执行之后调用该函数。
  • 必须返回一个实现了render方法的响应对象。通过response.template_name, response.context_data来修改传递的响应对象,也可以参加并绑定新的TemplateResponse对象。
  • 不需要明确指定render响应,影响将在所有模板响应中间件完成调用之后自动render。

5.4. process_request():

process_request(request)

  • request: 请求对象
  • 这个相当于__call__()中调用self.get_response(request)之前的代码部分
  • process_request和process_response要生效必须在__call__中明确指定调用,也可以通过继承:MiddlewareMixin类来隐式调用这两个方法。
class MiddlewareMixin(object):
def __init__(self, get_response):
self.get_response = get_response
super(MiddlewareMixin, self).__init__() def __call__(self, request):
response = None
if hasattr(self, 'process_request'):
response = self.process_request(request)
if not response:
response = self.get_response(request)
if hasattr(self, 'process_response'):
response = self.process_response(request, response)
return response

5.5. process_response():

process_response(request, response)

  • request: 请求对象,response: 响应对象
  • 这个相当于把self.get_response(request)返回的response对象,和reques对象传递给该函数,该函数在self.get_response(request)之后执行。

[TimLinux] Django 中间件的更多相关文章

  1. Django数据操作F和Q、model多对多操作、Django中间件、信号、读数据库里的数据实现分页

    models.tb.objects.all().using('default'),根据using来指定在哪个库里查询,default是settings中配置的数据库的连接名称. 外话:django中引 ...

  2. django 中间件

    django处理一个Request的过程是首先通过django 中间件,然后再通过默认的URL方式进行的.所以说我们要做的就是在django 中间件这个地方把所有Request拦截住,用我们自己的方式 ...

  3. day20 FORM补充(随时更新),F/Q操作,model之多对多,django中间件,缓存,信号

    python-day20 1.FROM生成select标签的数据应该来源于数据库. 2.model 操作 F/Q  (组合查询) 3.model 多对多操作. 4.中间件 :在请求到达url前先会经过 ...

  4. Django学习之七:Django 中间件

    目录 Django 中间件 自定义中间件 - - - 大体两种方式 将中间件移除 实例 中间件加载源码阅读 总结 Django 中间件 Tips: 更新日志: 2019.01.31 更新django中 ...

  5. Django中间件的使用

    Django中间件的使用 中间件(middleware) 中间件应用于request与服务端之间和服务端与response之间,客户端发起请求到服务端接收可以通过中间件,服务端返回响应与客户端接收响应 ...

  6. Django中间件 及 form 实现用户登陆

    Django中间件 及 form 实现用户登陆 Form 验证 密码调用md5 加密存储 form.add_error("字段名", "错误信息") 自定义错误 ...

  7. Django 2.0 学习(20):Django 中间件详解

    Django 中间件详解 Django中间件 在Django中,中间件(middleware)其实就是一个类,在请求到来和结束后,Django会根据自己的规则在合适的时机执行中间件中相应的方法. 1. ...

  8. Django中间件的5种自定义方法

    阅读目录(Content) Django中间件 自定义中间件 中间件(类)中5种方法 中间件应用场景 回到顶部(go to top) Django中间件 在http请求 到达视图函数之前   和视图函 ...

  9. Python自动化之Django中间件

    django中间件 Django请求生命周期 中间件中可以定义方法,分别是 process_request(self,request) process_view(self, request, call ...

随机推荐

  1. jquery mobiscroll移动端日期选择控件(无乱码)

    jquery mobiscroll移动端日期选择控件(无乱码) <pre><!DOCTYPE html><html lang="en">< ...

  2. docker项目——搭建飞机大战小游戏

    项目2:搭建打飞机小游戏,验证数据持久化(最底下有链接) 第一步:拉取镜像 [root@localhost docker-image]# docker load < httpd_img.tar. ...

  3. (十七)golang--闭包(简单明了)

    所谓闭包:就是一个函数和其相关的引用环境组合的一个整体: 首先,有如下一个小例子,最终的输出结果是什么呢?是输出11,12吗? 对上述代码说明:(1)addUpper是一个函数,返回的是func(in ...

  4. C++中对C的扩展学习新增语法——函数重载

    函数重载 1.函数重载语法 1.同一个作用域(全局作用域.命名空间作用域.类作用域) 2.参数个数不同 3.参数类型不同 4.参数顺序不同 代码实现: 当函数名字一样的时候,通过参数类型.参数个数.参 ...

  5. lqb 基础练习 字母图形 (循环)

    基础练习 字母图形 时间限制:1.0s   内存限制:256.0MB     问题描述 利用字母可以组成一些美丽的图形,下面给出了一个例子: ABCDEFG BABCDEF CBABCDE DCBAB ...

  6. Spring boot 加入shiro支持

    在项目添加依赖 <!-- shiro spring. --> <dependency> <groupId>org.apache.shiro</groupId& ...

  7. 力扣(LeetCode)2的幂 个人题解

    给定一个整数,编写一个函数来判断它是否是 2 的幂次方. 示例 1: 输入: 1 输出: true 解释: 20 = 1 示例 2: 输入: 16 输出: true 解释: 24 = 16 示这题是考 ...

  8. 2018.3.7java 学习第二天

    java 学习的第二天,首先我们要学习的是声明变量,在程序中,我们必须先声明变量,然后才可以去使用之,那么变量究竟是什么呢? 在很多课本上,有很多的定义诸如:“变量来源于数学,是计算机语言中能储存计算 ...

  9. 什么是PHP Socket?

    什么是 Socket? Socket 的中文翻译过来就是“套接字”.套接字是什么,我们先来看看它的英文含义:插座. Socket 就像一个电话插座,负责连通两端的电话,进行点对点通信,让电话可以进行通 ...

  10. 将py文件打包为exe文件方法

    前提: pip是依赖python的,首先检查下windows机器上有没有安装python,或者有没有添加到环境变量中,如果都没有需要安装或者加入环境变量 安装pip 下载地址: https://pyp ...