Django框架之中间件

news2024/9/23 3:34:11

目录

一、引入

二、Django中间件介绍

【1】什么是Django中间件

【2】Django中间件的作用

【3】示例

三、Django请求生命周期流程图

四、Django中间件是Django的门户

五、Django中间件详解

六、中间件必须要掌握的两个方法

(1)  process_request

(2)  process_response

七、自定义中间件

【1】process_request

【2】process_response

【3】小结


一、引入

  • Django自带七个中间件,每个中间件都有各自对应的功能
  • 并且Django支持用户自定义中间件
  • 在使用Django框架开发项目的时候,只要是涉及到全局相关的功能都可以使用中间件更加方便的完成
    • 比如全局身份校验
    • 全局用户权限校验
    • 全局访问频率的校验
    • ...

二、Django中间件介绍

【1】什么是Django中间件

  • Django中间件是一个轻量级、可重用的组件,用于处理Django请求和响应的过程。
  • 它提供了对请求和响应进行全局处理的机制,可以在请求达到视图之前进行预处理或在响应返回给客户端之前进行后处理。
  • 中间件是按照顺序依次执行的,每个中间件都可以对请求和响应进行修改、补充或处理。
  • 在Django的settings.py配置文件中,通过MIDDLEWARE设置来定义中间件的顺序。

【2】Django中间件的作用

  • 认证和授权:
    • 中间件可以在请求到达视图之前进行用户认证和权限验证,确保只有经过授权的用户才能访问敏感资源。
  • 请求和响应处理:
    • 中间件可以在请求到达视图之前对请求进行预处理
      • 例如添加请求头信息、检查请求参数的合法性等操作。
    • 同时,在视图函数返回响应给客户端之前,中间件还可以对响应进行后处理
      • 例如添加额外的响应头、包装响应数据等操作。
  • 异常处理:
    • 中间件还可以捕获视图函数中可能抛出的异常,并做相应的处理
      • 例如记录异常日志、返回自定义错误信息等。
  • 性能优化:
    • 通过中间件,可以对请求进行性能监测、缓存处理、压缩响应等操作,提升网站的整体性能。

【3】示例

class MyMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response
 
    def __call__(self, request):
        # 在视图函数调用之前的预处理逻辑
        # ...
 
        response = self.get_response(request)
 
        # 在响应返回给客户端之前的后处理逻辑
        # ...
 
        return response

三、Django请求生命周期流程图

  • 当客户端发送一个请求到Django应用程序时,Django会按照一定的生命周期流程处理该请求。
    • 客户端发出HTTP请求。
    • 请求被Web服务器接收并传递给Django应用程序。
    • Django中的WSGI中间件开始处理请求,并可进行一些预处理操作。
    • 中间件将请求传递给URL分发器(URL Dispatcher)。
    • URL分发器根据URL模式将请求路由到相应的视图函数或处理器(View/Handler)。
    • 视图函数或处理器执行相应的业务逻辑,可能会与数据库等外部资源交互。
    • 视图函数或处理器返回一个HTTP响应对象。
    • 响应对象经过中间件,可以在此进行后处理操作。
    • 响应被发送给Web服务器。
    • Web服务器将响应发送回客户端。

四、Django中间件是Django的门户

  • 请求发来的时候需要先经过中间件才能到达真正的Django后端
  • 响应返回的时候,最后也需要进过中间件返回发送出去

五、Django中间件详解

(1)  SecurityMiddleware

  • django.middleware.security.SecurityMiddleware:
    • 安全中间件负责处理与网站安全相关的任务
    • 例如设置HTTP头部,防止跨站脚本攻击(XSS),点击劫持等。
    • 它可以通过配置自定义安全策略来确保网站的安全性。

(2)  SessionMiddleware

  • django.contrib.sessions.middleware.SessionMiddleware:
    • 会话中间件负责处理用户会话的创建之间存储和检索用户数据。
    • 它基于浏览器提供的Cookie或URL传递的会话ID进行会话跟踪,并将会话数据存储在后端数据库或缓存中,以实现用户状态的跨请求保持。

(3)  CommonMiddleware

  • django.middleware.common.CommonMiddleware:
    • 通用中间件提供了一些常见而关键的HTTP请求处理功能
    • 例如,根据请求的HTTP头信息设置语言、时区等。
    • 此外,它还处理静态文件的serving,包括收集静态文件,为其生成URL,并在开发模式下提供静态文件的serving。

(4)  CsrfViewMiddleware

  • django.middleware.csrf.CsrfViewMiddleware:
    • CSRF(Cross-Site Request Forgery)中间件用于防止跨站请求伪造攻击。
    • 它在每个POST请求中验证一个CSRF标记,确保请求是通过合法的表单提交得到的,从而保护用户免受恶意站点的攻击。

(5)  AuthenticationMiddleware

  • django.contrib.auth.middleware.AuthenticationMiddleware:
    • 认证中间件负责处理用户身份认证相关的任务
    • 例如将认证信息关联到请求对象上,为每个请求提供一个user对象,以便在请求处理过程中轻松地获取和使用用户身份信息。

(6)  MessageMiddleware

  • django.contrib.messages.middleware.MessageMiddleware:
    • 消息中间件用于在请求处理过程中存储和传递临时的、一次性的用户消息。
    • 它允许在HTTP重定向之间跨请求传递消息,例如成功或错误提示,以改善用户体验。

(7)  XFrameOptionsMiddleware

  • django.middleware.clickjacking.XFrameOptionsMiddleware:
    • 点击劫持中间件用于防止页面被嵌入到其他网站中,从而提供一定的点击劫持保护。
    • 它通过设置X-Frame-Options HTTP头部来限制页面的显示方式,从而防止恶意网页通过iframe等方式嵌入当前网页。

六、中间件必须要掌握的两个方法

(1)  process_request

(1)执行顺序

  • 请求来的时候需要经过每一个中间件的 process_request 方法
  • 结果的顺序是按照配置文件中注册的中间件从上往下的顺序执行的

(2)没有定义process_request

  • 如果没有定义这个方法,就跳过这个中间件

(3)定义了返回值

  • 如果在自定义中间件中定义了返回值(三板斧),那么请求将不再继续执行,而是直接原路返回(校验失败不允许访问)

(4)总结

  • process_request 方法就是用来 做全局相关的所有限制功能
  • 该方法在每个请求到达视图之前被调用,可以对请求进行预处理。
    • 例如,进行身份验证、访问控制或请求日志记录等操作。
  • 它接收一个HttpRequest对象作为参数,并且没有返回值

示例:

class AuthenticationMiddleware:
    def process_request(self, request):
        # 在这里进行身份验证操作
        if not request.user.is_authenticated:
            # 如果用户未经身份验证,则返回HttpResponse或重定向到登录页面

(2)  process_response

  • 响应被返回的时候需要结束每一个中间件里面的 process_response 方法
    • 该方法有两个额外的参数
      • request
      • response
  • 该方法必须返回 HttpResponse 对象
    • 默认是response
    • 支持自定义
  • 顺序是按照配置文件中注册过的中间件从下往上依次经过
    • 如果没有定义,则跳过,校验下一个
  • 该方法在每个请求结束并且响应返回到客户端之前被调用。
    • 可以在此处对响应进行处理
    • 例如添加额外的头信息、修改响应内容等。
  • 它接收一个HttpRequest对象和HttpResponse对象作为参数,并且必须返回一个HttpResponse对象。

示例:

class CustomResponseMiddleware:
    def process_response(self, request, response):
        # 在这里对响应进行处理
        response['X-Custom-Header'] = 'Custom Value'
        return response

七、自定义中间件

【1】process_request

  • 路由层
from app01 import views
 
urlpatterns = [
    path('admin/', admin.site.urls),
    path('index/',views.index),
]
  • 视图层 
def index(request):
    print("这是视图函数index")
    return HttpResponse("index 的返回值")
  • 配置文件 
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.mymiddle.my_middle.MyMiddle',
    # 谁先注册就先执行谁
    'app01.mymiddle.my_middle.MyMiddle2',
]
  • 自定义中间件 
# 引入父类
from django.utils.deprecation import MiddlewareMixin
 
 
class MyMiddle(MiddlewareMixin):
    def process_request(self, request):
        print("这是第一个自定义中间件中的 process_request 方法")
 
class MyMiddle2(MiddlewareMixin):
    def process_request(self, request):
        print("这是第二个自定义中间件中的 process_request 方法")

【2】process_response

# 引入父类
from django.utils.deprecation import MiddlewareMixin
 
 
class MyMiddle(MiddlewareMixin):
    def process_request(self, request):
        print("这是第一个自定义中间件中的 process_request 方法")
 
    def process_response(self, request, response):
        '''
        
        :param request: 
        :param response: 就是Django返回给浏览器的内容
        :return: 
        '''
        print("这是第一个自定义中间件中的 process_response 方法")
        # 必须返回 responser
        return response

【3】小结

  • 如果在第一个 process_request 方法就已经返回了 HttpResponse 对象,那么响应被返回的时候是经过所有的中间件里面的 process_response 方法还是会发生其他?
    • 会直接走同级别的 process_response 方法 ,然后直接返回
  • flask框架的中间件也有一个类似的方法
    • 但是flask返回数据就必须经过所有中间件里面的 process_response 方法

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

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

相关文章

支持对协议和会话分享动作进行授权,新增API Key白名单功能,JumpServer堡垒机v3.9.0发布

2023年11月20日,JumpServer开源堡垒机正式发布v3.9.0版本。在这一版本中,JumpServer对授权功能进行了优化,增加了对“会话分享”及“资产协议”的配置,方便管理员以更细的颗粒度对各种资源进行控制;针对使用API Key与J…

教你看现货黄金实时报价

现货黄金投资市场上的交易软件众多,很多人不知道选择什么软件好,但选择主流软件MT4,基本就可以满足投资者不同的需求。本文为大家讲讲,为什么有那么多的投资者,都选择通过MT4获取实时的行情报价。 现货黄金市场波动激烈…

Linux中flask项目开启https访问

1.下载阿里云免费证书 2.项目添加https配置 3.服务器开启https访问 3.1 重新安装OpenSSL 3.2.重新安装Python 上一次已经讲过Linux安装部署Python: Linux安装Python3.10与部署flask项目实战详细记录,今天记录一下Python项目如何支持https访问…

免费开源 GPU池化软件 | (AI人工智能训练平台、AI人工智能推理平台)全套源码

GPU池化软件 | (AI人工智能训练平台、AI人工智能推理平台) 讨论群v:🚀18601938676 一、AI人工智能开发-------------面临的问题和挑战 1. GPU管理难题 1.1 资源管理难:算力资源昂贵,但是缺乏有效管理,闲置情况严重。 1.2 用户…

RabbitMQ快速学习之WorkQueues模型、三种交换机、消息转换器(SpringBoot整合)

文章目录 前言一、WorkQueues模型消息发送消息接收能者多劳 二、交换机类型1.Fanout交换机消息发送消息接收 2.Direct交换机消息接收消息发送 3.Topic交换机消息发送消息接收 三、编程式声明队列和交换机fanout示例direct示例基于注解 四、消息转换器总结 前言 WorkQueues模型…

【2023-11-23】生成A~Z编号

生成A~Z编号 需要生成 A~Z的编号,当新的编号超过Z时,从A1开始,依次为B1 C1一直至Z1,如此循环。 最大支持字母为Z,超过后以添加数字后缀的形式标记 简单代码 默认从A开始循环 function getLimitNumber(_total) {var num 0var …

轻松管理文件名:文件批量重命名的技巧与操作

在日常工作中,文件管理是一项至关重要的任务。其中,文件名的管理更是关键。文件名是在查找文件时最直观的线索。一个好的文件名简短而准确地反映文件的内容或用途。然而,随着时间的推移,可能会发现文件名变得冗长、混乱甚至无法反…

壳牌——利用人工智能应对新能源转型

荷兰皇家壳牌(Shell)最初是一家卖贝壳的商店,截至 2018 年,它是全球收入排名第五的公司。它的业务范围涵盖从勘探和钻探到提炼和零售的整个燃料供应链。壳牌在石油、天然气、生物燃料、风能和太阳能等端到端燃料生产领域处于世界领先地位。 当前&#x…

【算法】缓存淘汰算法

目录 1.概述2.代码实现2.1.FIFO2.2.LRU2.3.LFU2.4.Clock2.5.Random 3.应用 1.概述 缓存淘汰策略是指在缓存容量有限的情况下,当缓存空间不足时决定哪些缓存项应当被移除的策略。缓存淘汰策略的目标是尽可能地保持缓存命中率高,同时合理地利用有限的缓存…

【Linux系统编程二十】:(进程通信2)--命名管道/共享内存

【Linux系统编程二十】:命名管道/共享内存 一.命名管道1.创建管道2.打开管道3.进行通信(server/client) 二.共享内存1.实现原理2.申请内存3.挂接4.通信5.去关联6.释放共享内存7.特性: 一.命名管道 上一篇介绍的一个管道是没有名字的 因为你打开那个文件…

前端工程、静态代码、Html页面 打包成nginx 的 docker镜像

1. 创建一个 mynginx的目录 2. 将前端代码文件夹(比如叫 front )复制到 mynginx 目录下 3. 在mynginx 目录下创建一个名为Dockerfile 的文件(文件名不要改),文件内容如下: # 使用官方的 Nginx 镜像作为基…

【C++】泛型编程 ⑭ ( 类模板示例 - 数组类模板 | 容器思想 | 自定义类可拷贝 - 深拷贝与浅拷贝 | 自定义类可打印 - 左移运算符重载 )

文章目录 一、容器思想1、自定义类可拷贝 - 深拷贝与浅拷贝2、自定义类可拷贝 - 代码示例3、自定义类可打印 - 左移运算符重载 二、代码示例1、Array.h 头文件2、Array.cpp 代码文件3、Test.cpp 主函数代码文件4、执行结果 一、容器思想 1、自定义类可拷贝 - 深拷贝与浅拷贝 上…

企业软件定制开发的优势|app小程序网站搭建

企业软件定制开发的优势|app小程序网站搭建 企业软件定制开发是一种根据企业特定需求开发定制化软件的服务。相比于购买现成的软件产品,企业软件定制开发具有许多优势。 1.企业软件定制开发可以满足企业独特需求。每个企业都有自己独特的业务流程和需求,…

为什么vue中数组和对象的props默认值要写成函数形式?

多个组件数据不相互干涉 假如在一个地方引用了同一个组件,并给他们都绑定了单独的值。如果只声明为一个对象或数组,可能会导致在某一个实例中修改数据,影响到其他实例中的数据,因为数组和对象是引用类型的数据。为了在多次引用组件…

揭秘:如何精准定位性能瓶颈,优化系统性能?

你好,我是静姐,目前在一家准一线互联网大厂做测试开发工程师。对于一般公司普通测试工程师来说,可能性能测试做的并不是很复杂,可能只是编写下脚本,做个压测,然后输出报告结果,瓶颈分析和调优的…

ubuntu安装cuda驱动报错及解决,屡试不爽

机器重启输入nvidia-smi提示如下错误,字面意思就是驱动和库不匹配 Failed to initialize NVML: Driver/library version mismatch 查看一下nvidia相关库 sudo dpkg --list | grep nvidia-* 将所有已安装库卸载 sudo apt purge nvidia-* 重新安装驱动 sudo ./NVIDIA-Linux-…

Java实现王者荣耀小游戏

主要功能 键盘W,A,S,D键:控制玩家上下左右移动。按钮一:控制英雄发射一个矩形攻击红方小兵。按钮控制英雄发射魅惑技能,伤害小兵并让小兵停止移动。技能三:攻击多个敌人并让小兵停止移动。普攻:对小兵造成基础伤害。小…

redis的集群,主从复制,哨兵

redis的高可用 在Redis中,实现高可用的技术主要包括持久化、主从复制、哨兵和集群,下面分别说明它们的作用,以及解决了什么样的问题。 持久化: 持久化是最简单的高可用方法(有时甚至不被归为高可用的手段)…

京东大数据分析:2023年10月手机行业销量同比增长249%

今年双11,手机仍是竞争极为激烈的产品品类,各大手机厂商均在双11之前做足了准备,10月下旬,各电商平台双十一预售正式开启。而在双11大促节的参与下,10月份手机市场的整体销售也呈现增长趋势。 根据鲸参谋平台的数据显示…

mybatis 基本操作 删除 插入 更新 查询

根据主键删除数据 插入数据 -- 插入 insert into emp(username, name, gender, image, job, entrydate, dept_id, create_time, update_time) values (tom,塔姆,tom,1 , 1.png ,now(),1,now(),now() Options(keyProperty "id",useGeneratedKeys true) Insert(&quo…