Django中间件探索:揭秘中间件在Web应用中的守护角色与实战应用

在这里插入图片描述

系列文章目录

  • Django入门全攻略:从零搭建你的第一个Web项目
  • Django ORM入门指南:从概念到实践,掌握模型创建、迁移与视图操作
  • Django ORM实战:模型字段与元选项配置,以及链式过滤与QF查询详解
  • Django ORM深度游:探索多对一、一对一与多对多数据关系的奥秘与实践
  • 跨域问题与Django解决方案:深入解析跨域原理、请求处理与CSRF防护
  • Django视图层探索:GET/POST请求处理、参数传递与响应方式详解
  • Django路由与会话深度探索:静态、动态路由分发,以及Cookie与Session的奥秘
  • Django API开发实战:前后端分离、Restful风格与DRF序列化器详解
  • Django REST framework序列化器详解:普通序列化器与模型序列化器的选择与运用
  • Django REST framework关联序列化器详解:掌握复杂关系的序列化与反序列化艺术
  • Django REST framework中GenericAPIView与混入扩展类详解
  • Django REST framework视图集与路由详解:深入理解ViewSet、ModelViewSet与路由映射器
  • Django中间件探索:揭秘中间件在Web应用中的守护角色与实战应用
  • 还在写0.0…

文章目录

  • 系列文章目录
  • 前言
  • 一、默认中间件
    • 1. 中间件作用
    • 2. 中间件执行顺序
  • 二、自定义中间件
    • 1. 钩子方法的种类
    • 2. 自定义中间件
      • a. 自定义中间件并注册
      • b. 提供一个测试中间件效果的正确视图
      • c. 提供一个测试中间件效果的错误视图
      • d. 提供一个测试中间件效果的模板视图


前言

    Django中间件 是Web应用中的隐形守护者,负责在请求与响应之间执行关键任务。本文将解析Django默认中间件的作用,并教你如何编写和注册自定义中间件。通过实际案例,你将了解中间件在视图处理、错误处理和模板渲染中的作用。


一、默认中间件

1. 中间件作用

     Django中的中间件是一个轻量级、底层的插件系统,可以介入Django的请求和响应处理过程,全局修改Django的输入或输出。

     中间件的设计为开发者提供了一种无侵入式的开发方式,增强了Django框架的健壮性。我们可以使用中间件,在Django处理视图的不同阶段对输入或输出进行干预。

因为改变的是全局,所以需要谨慎使用,用不好会影响到性能.
作用: 在不改 django框架源代码的基础上 新增全局的扩展功能

  • 本质就是个装饰器 - - - 中间件只需要添加一次, 所有的接口都生效

2. 中间件执行顺序

在这里插入图片描述

  • 如果你想修改请求,例如被传送到view中的**HttpRequest对象。 或者你想修改view返回的HttpResponse**对象,这些都可以通过中间件来实现。
  • 可能你还想在view执行之前做一些操作,这种情况就可以用 middleware来实现。

Django默认的中间件:(在django项目的settings模块中,有一个 MIDDLEWARE_CLASSES 变量,其中每一个元素就是一个中间件,如下图)
在这里插入图片描述
在这里插入图片描述

#settings.py
MIDDLEWARE = ['django.middleware.security.SecurityMiddleware',# 为request/response提供了几种xss脚本过滤的安全改进,无它不安全'django.contrib.sessions.middleware.SessionMiddleware',# 开启session会话支持,无它无session'django.middleware.common.CommonMiddleware',# 基于APPEND_SLASH和PREPEND_WWW的设置来重写URL,# 如果APPEND_SLASH设为True,并且初始URL 没有以斜线结尾以及在URLconf 中没找到对应定义,这时形成一个斜线结尾的新URL;# 如果PREPEND_WWW设为True,前面缺少 www.的url将会被重定向到相同但是以一个www.开头的ur'django.middleware.csrf.CsrfViewMiddleware',# 添加跨站点请求伪造的保护,通过向POST表单添加一个隐藏的表单字段,并检查请求中是否有正确的值,无它无csrf保护'django.contrib.auth.middleware.AuthenticationMiddleware',# 在视图函数执行前向每个接收到的user对象添加HttpRequest属性,表示当前登录的用户,无它用不了request.user'django.contrib.messages.middleware.MessageMiddleware',# 开启基于Cookie和会话的消息支持,无它无message'django.middleware.clickjacking.XFrameOptionsMiddleware',# 对点击劫持的保护
]

二、自定义中间件

1. 钩子方法的种类

    django中默认给咱们提供了几个中间件,如果在过程中开发者想自己对请求和响应做出特殊处理,需要自己定义一个中间件,自定义的中间件需要继承 django.utils.deprecation.MiddlewareMixin这个类。并重写对应的方法。

中间件中重写的5个方法:

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或一个HttpResponse对象,如果是None,则继续按照django定义的规则向后继续执行,如果是HttpResponse对象,则直接将该对象返回给用户。

2. 自定义中间件

a. 自定义中间件并注册

自定义中间件 示例代码如下:

# customMiddleware.py
from django.http import HttpResponse
from django.utils.deprecation import MiddlewareMixinclass CustomMiddleware(MiddlewareMixin):def process_request(self, request):"""处理请求前: 在每个请求上,request对象产生之后,url匹配之前调用,返回None或HttpResponse对象"""print('before request=====', request)def process_view(self, request, view_func, *view_args, **view_kwargs):""":param view_func: Django即将使用的视图函数,它是实际的函数对象,而不是函数的名称作为字符串:param view_args: 将传递给视图的位置参数的列表:param view_kwargs: 将传递给视图的关键字参数的字典;view_args和view_kwargs都不包含第一个视图参数(request)"""# 处理视图前:在每个请求上,url匹配之后,视图函数调用之前调用,返回None或HttpResponse对象print('before view=======')def process_template_response(self, request, response):# 在视图函数执行完后立即执行的, 执行 该 函数有一个前提条件,那就是视图函数返回的对象是一个 TemplateResponse 对象或等价方法, 直接返回render函数无效)print("render template=======")return responsedef process_exception(self, request, exception):# 这个方法只有在视图函数中出现异常了才执行,它返回的值可以是一个None也可以是一个HttpResponse对象print("raise exception=======")return HttpResponse(exception)def process_response(self, request, response):# 处理响应后:视图函数调用之后,所有响应返回浏览器之前被调用,在每个请求上调用,返回HttpResponse对象print('after response=======', response)return response

在process_response中可以实现将返回数据修改操作 ,示例代码(此代码只可以响应drf的Response有效,因为普通HttpResponse中没有data属性):

from django.utils.encoding import force_str, force_bytes
import jsondef process_response(self, request, response):if response['Content-Type'] == 'application/json':# 解码JSON数据data = json.loads(force_str(response.content))# 修改数据data['modified_key'] = 'modified_value'# 重新编码JSON数据response.content = force_bytes(json.dumps(data))return response

注册中间件:
django 项目的 settings 模块中,在 MIDDLEWARE_CLASSES 变量中添加自定义中间件

MIDDLEWARE = [# 添加自定义的中间件---CustomMiddleware'app.customMiddleware.CustomMiddleware','corsheaders.middleware.CorsMiddleware','django.middleware.security.SecurityMiddleware',......
]

b. 提供一个测试中间件效果的正确视图

b.提供一个测试中间件效果的正确视图:

# views.py
from rest_framework.views import APIView
from django.http import HttpResponse# Create your views here.class IndexView(APIView):def get(self, request):print("IndexView======================")return HttpResponse("Hello Index GET")

当用户发起请求的时候会依次经过所有的的中间件,这个时候的请求会依次穿过所有中间件的process_request方法,最后到达views的函数中,views函数处理后,在依次穿过所有中间件的process_response方法,最后返回给请求者。

中间件执行结果展示:
访问路径:http://localhost:8000/app/index/

before request===== <WSGIRequest: GET '/app/index/'>
before view=======
IndexView======================
after response======= <HttpResponse status_code=200, "text/html; charset=utf-8">
[16/Jun/2024 19:55:45] "GET /app/index/ HTTP/1.1" 200 15

c. 提供一个测试中间件效果的错误视图

c.提供一个测试中间件效果的错误视图:

# views.py
from rest_framework.views import APIView
from django.http import HttpResponse# Create your views here.class IndexView(APIView):def get(self, request):print("IndexView======================")3/0return HttpResponse("Hello Index GET")

此时,视图发生异常, 会执行中间件的 process_exception方法,而在该方法中,将异常信息作为响应返回,因此,页面显示"division by zero"

中间件执行结果展示:
访问路径:http://localhost:8000/app/index/
在这里插入图片描述

before request===== <WSGIRequest: GET '/app/index/'>
before view=======
IndexView======================
raise exception=======
after response======= <HttpResponse status_code=200, "text/html; charset=utf-8">
[16/Jun/2024 19:58:22] "GET /app/index/ HTTP/1.1" 200 16

d. 提供一个测试中间件效果的模板视图

d.提供一个测试中间件效果的模板视图:

# views.py
from django.template.response import TemplateResponse
from rest_framework.views import APIView# Create your views here.class IndexView(APIView):def get(self, request):print("IndexView======================")return TemplateResponse(request, 'index.html')

注意: 只有返回的对象是TemplateResponse 对象或等价方法时,才执行中间件的 process_template_response方法,直接调用render方法无效。

中间件执行结果展示:
访问路径:http://localhost:8000/app/index/
在这里插入图片描述

before request===== <WSGIRequest: GET '/app/index/'>
before view=======
IndexView======================
render template=======
after response======= <TemplateResponse status_code=200, "text/html; charset=utf-8">
[16/Jun/2024 19:59:20] "GET /app/index/ HTTP/1.1" 200 182

TemplateResponse VS render

  • TemplateResponse将模板的渲染延迟到视图完成之后。这允许任何模板响应中间件在响应上运行,并有可能在呈现模板之前更改模板或上下文数据。模板响应中间件运行后,将渲染模板,并在将响应返回给客户端之前对渲染的内容运行常规响应中间件。
  • render立即呈现模板,并返回HttpResponse

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/28455.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Git管理(Linux版本)

在Linux中我们如何把自己的代码上传到gitee中呢&#xff0c;本期将为大家讲解详细的步骤。 目录 查看Linux环境是否存在git工具 在gitee上创建代码仓库 复制仓库的HTTP路径到Linux中 代码上传 在仓库下创建文件或者将文件移动到仓库下 使用三板斧进行文件的上传 add …

Podman常用命令

Podman 是 Red Hat 的一个开源项目&#xff0c;可以免费下载。它是容器化领域的一个相对较新的人&#xff0c;1.0 版将于 2019 年发布。此后 Podman 取得了长足的进步&#xff0c;其崛起伴随着 Docker 的逐渐衰落&#xff0c;该项目在许多方面创造了我们今天所知的容器世界。 容…

使用 Oracle SQL Developer 导入数据

使用 Oracle SQL Developer 导入数据 1. 导入过程 1. 导入过程 选择要导入数据的表&#xff0c; 然后单击右键&#xff0c;选择"导入数据"&#xff0c; 浏览本地文件&#xff0c;选择正确的工作表&#xff0c; 按默认&#xff0c; 按默认&#xff0c; 根据情况修改&…

2. 机器学习概述

机器学习是对能通过经验自动改进的计算机算法的研究。 ---汤姆. 米切尔 1997 通俗来讲&#xff0c;机器学习就是让计算机从数据中进行自动学习&#xff0c;得到某种知识&#xff08;或规律&#xff09;。在早期的工程领域&#xff0c;机器学习也经常被称为模式识别&#xff08;…

guli商城业务逻辑-基础篇笔记

这里写目录标题 0.1 viscode设置用户代码片段1.实现多级菜单接口1.1 对接前端菜单1.2 对接网关接口解决跨域问题&#xff0c;如果不解决跨域&#xff0c;浏览器还是访问不了api1.3 把商品服务添加网关1.4 修改前端显示分类菜单1.5 给菜单添加删除修改功能1.5.1 删除功能的后端业…

Oracle 入门--前提

目录 1.sqlplus 2.dual是什么&#xff1f; 3.SQL语句的种类 4.Oracle是如何工作的 5.Oracle查看配置文件 6.修改配置文件 7.常用的参数设置 1.sqlplus 管理数据库&#xff1a;启动&#xff0c;关闭&#xff0c;创建&#xff0c;删除对象......查看数据库的运行状态&…

【分布式计算】java消息队列机制

消息队列是一种在不同组件或应用之间进行数据传递的技术&#xff0c;通常用于处理异步通信。它允许消息的发送者&#xff08;生产者&#xff09;和接收者&#xff08;消费者&#xff09;之间进行解耦。 概念 消息队列是一种先进先出&#xff08;FIFO&#xff09;的数据结构&…

机器学习(V)--无监督学习(一)聚类

根据训练样本中是否包含标签信息&#xff0c;机器学习可以分为监督学习和无监督学习。聚类算法是典型的无监督学习&#xff0c;目的是想将那些相似的样本尽可能聚在一起&#xff0c;不相似的样本尽可能分开。 相似度或距离 聚类的核心概念是相似度(similarity)或距离(distance…

嵌入式学习记录6.14(练习)

#include "mainwindow.h" #include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow) {ui->setupUi(this);this->resize(1028,783); //设置左侧背景QLabel *lab1new QLabel(this);lab1->…

【内存管理之堆内存】

1.栈上的基元 2.栈上的聚合对象 3.手动分配和释放 4.分配堆内存 5.数组内存分配和释放 6.数组内存分配 7.不要使用野指针 8.黑暗时代

STM32理论 —— μCOS-Ⅲ(2/2):时间管理、消息队列、信号量、任务内嵌信号量/队列、事件标志、软件定时器、内存管理

文章目录 9. 时间管理9.1 OSTimeDly()9.2 OSTimeDlyHMSM()9.3 OSTimeDlyResume()9.4 延时函数实验 10. 消息队列10.1 创建消息队列函数OSQCreate()10.2 发送消息到消息队列函数(写入队列)OSQPost()10.3 获取消息队列中的消息函数(读出队列)OSQPend()10.4 消息队列操作实验 11. …

12 款 Android 照片恢复应用程序列表

丢失难忘的照片总是令人痛苦的。如果软件崩溃或意外删除&#xff0c;Android 设备上的照片也可能会丢失。这时照片恢复应用程序就派上用场了。查看我们为 Android 收集的顶级照片恢复应用程序。 但是&#xff0c;您不会想为自己选择任何照片恢复应用程序。因此&#xff0c;我们…

Doris:冷热分层

目录 一、冷热分层介绍 二、存储策略&#xff08;Storage policy&#xff09; 2.1 创建存储资源 2.2 创建存储策略 2.3 使用存储策略 三、使用限制 一、冷热分层介绍 冷热分层支持所有 Doris 功能&#xff0c;只是把部分数据放到对象存储上&#xff0c;以节省成本&am…

openGauss 6.0.0 一主二备集群安装及使用zcbus实现Oracle到openGauss的数据同步

一、前言 openGauss 6.0.0-RC1是openGauss 2024年3月发布的创新版本&#xff0c;该版本生命周期为0.5年。根据openGauss官网介绍&#xff0c;6.0.0-RC1与之前的版本特性功能保持兼容,另外&#xff0c;在和之前版本兼容的基础上增加了很多新功能&#xff0c;比如分区表性能优化…

go的netpoll学习

go的运行时调度框架简介 Go的运行时&#xff08;runtime&#xff09;中&#xff0c;由调度器管理&#xff1a;goroutine&#xff08;G&#xff09;、操作系统线程&#xff08;M&#xff09;和逻辑处理器&#xff08;P&#xff09;之间的关系 以实现高效的并发执行 当一个gorout…

统计完全子字符串

很不错的计数问题&#xff0c;用到了分组循环技巧和滑动窗口 代码的实现方式也非常值得多看 class Solution { public:int f(string s,int k){int res 0;for(int m1;m<26&&k*m<s.size();m){int cnt[27]{};auto check[&](){for(int i0;i<26;i){if(cnt[i]…

跟着刘二大人学pytorch(第---10---节课之卷积神经网络)

文章目录 0 前言0.1 课程链接&#xff1a;0.2 课件下载地址&#xff1a; 回忆卷积卷积过程&#xff08;以输入为单通道、1个卷积核为例&#xff09;卷积过程&#xff08;以输入为3通道、1个卷积核为例&#xff09;卷积过程&#xff08;以输入为N通道、1个卷积核为例&#xff09…

计算机组成原理之定点除法

文章目录 定点除法运算原码恢复余数法原码不恢复余数法&#xff08;加减交替法&#xff09;运算规则 习题 定点除法运算 注意 &#xff08;1&#xff09;被除数小于除数的时候&#xff0c;商0 &#xff08;2&#xff09;接下来&#xff0c;有一个除数再原来的基础上&#xff0c…

springboot + Vue前后端项目(第十六记)

项目实战第十六记 写在前面1 第一个bug1.1 完整的Role.vue 2 第二个bug2.1 修改路由router下面的index.js 总结写在最后 写在前面 发现bug&#xff0c;修复bug 1 第一个bug 分配菜单时未加入父id&#xff0c;导致分配菜单失效 <!-- :check-strictly"true" 默…

图的应用之最小生成树

大纲 生成树介绍 特点 但n个 种类 最小生成树 应用 构造算法 MST性质 Prim算法 依次选择与顶点相邻的不会构成回路的最小边对应的顶点 Kruskal算法 依次选不会构成环的最小边 区别 Prim算法有n个顶点进行选择&#xff0c;每个顶点有n个选择&#xff0c;复杂度为O(n*n) K…