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

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

前言

    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 MiddlewareMixin
class 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 response
    def 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 json
def 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/0
        return 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


相关文章
|
5月前
|
人工智能 安全 中间件
阿里云 AI 中间件重磅发布,打通 AI 应用落地“最后一公里”
9 月 26 日,2025 云栖大会 AI 中间件:AI 时代的中间件技术演进与创新实践论坛上,阿里云智能集团资深技术专家林清山发表主题演讲《未来已来:下一代 AI 中间件重磅发布,解锁 AI 应用架构新范式》,重磅发布阿里云 AI 中间件,提供面向分布式多 Agent 架构的基座,包括:AgentScope-Java(兼容 Spring AI Alibaba 生态),AI MQ(基于Apache RocketMQ 的 AI 能力升级),AI 网关 Higress,AI 注册与配置中心 Nacos,以及覆盖模型与算力的 AI 可观测体系。
1175 56
|
5月前
|
存储 前端开发 Java
【JAVA】Java 项目实战之 Java Web 在线商城项目开发实战指南
本文介绍基于Java Web的在线商城技术方案与实现,涵盖三层架构设计、MySQL数据库建模及核心功能开发。通过Spring MVC + MyBatis + Thymeleaf实现商品展示、购物车等模块,提供完整代码示例,助力掌握Java Web项目实战技能。(238字)
587 0
|
7月前
|
数据采集 自然语言处理 NoSQL
利用中间件实现任务去重与分发精细化:股吧舆情数据采集与分析实战
本项目针对东方财富股吧设计精细化采集方案,解决重复采集、调度混乱与反爬等问题,构建舆情分析数据模型。通过采集帖子内容、用户行为与情绪信号,实现情绪趋势可视化、热点识别与个股预警,助力把握市场风向。
350 0
利用中间件实现任务去重与分发精细化:股吧舆情数据采集与分析实战
|
9月前
|
前端开发 算法 API
构建高性能图像处理Web应用:Next.js与TailwindCSS实践
本文分享了构建在线图像黑白转换工具的技术实践,涵盖技术栈选择、架构设计与性能优化。项目采用Next.js提供优秀的SSR性能和SEO支持,TailwindCSS加速UI开发,WebAssembly实现高性能图像处理算法。通过渐进式处理、WebWorker隔离及内存管理等策略,解决大图像处理性能瓶颈,并确保跨浏览器兼容性和移动设备优化。实际应用案例展示了其即时处理、高质量输出和客户端隐私保护等特点。未来计划引入WebGPU加速、AI增强等功能,进一步提升用户体验。此技术栈为Web图像处理应用提供了高效可行的解决方案。
|
5月前
|
存储 JavaScript 安全
Web渗透-XSS漏洞深入及xss-labs靶场实战
XSS(跨站脚本攻击)是常见的Web安全漏洞,通过在网页中注入恶意脚本,窃取用户信息或执行非法操作。本文介绍其原理、分类(反射型、存储型、DOM型)、测试方法及xss-labs靶场实战案例,帮助理解与防御XSS攻击。
1765 1
Web渗透-XSS漏洞深入及xss-labs靶场实战
|
5月前
|
安全 Linux PHP
Web渗透-命令执行漏洞-及常见靶场检测实战
命令执行漏洞(RCE)指应用程序调用系统命令时,用户可控制输入参数,导致恶意命令被拼接执行,从而危害系统安全。常见于PHP的system、exec等函数。攻击者可通过命令连接符在目标系统上执行任意命令,造成数据泄露或服务瘫痪。漏洞成因包括代码层过滤不严、第三方组件缺陷等。可通过参数过滤、最小权限运行等方式防御。本文还介绍了绕过方式、靶场测试及复现过程。
1259 0
|
6月前
|
缓存 监控 中间件
Django中间件自定义开发指南:从原理到实战的深度解析
Django中间件是Web应用的“交通警察”,在请求与响应过程中进行全局处理,适用于身份验证、日志记录、性能监控等功能。本文详解中间件的工作原理、开发步骤及实战案例,帮助开发者掌握自定义中间件的构建方法,提升Django应用的可维护性与扩展性。
372 0
|
8月前
|
开发框架 JSON 中间件
Go语言Web开发框架实践:路由、中间件、参数校验
Gin框架以其极简风格、强大路由管理、灵活中间件机制及参数绑定校验系统著称。本文详解其核心功能:1) 路由管理,支持分组与路径参数;2) 中间件机制,实现全局与局部控制;3) 参数绑定,涵盖多种来源;4) 结构体绑定与字段校验,确保数据合法性;5) 自定义校验器扩展功能;6) 统一错误处理提升用户体验。Gin以清晰模块化、流程可控及自动化校验等优势,成为开发者的优选工具。
|
8月前
|
Linux 数据库 数据安全/隐私保护
Python web Django快速入门手册全栈版,共2590字,短小精悍
本教程涵盖Django从安装到数据库模型创建的全流程。第一章介绍Windows、Linux及macOS下虚拟环境搭建与Django安装验证;第二章讲解项目创建、迁移与运行;第三章演示应用APP创建及项目汉化;第四章说明超级用户创建与后台登录;第五章深入数据库模型设计,包括类与表的对应关系及模型创建步骤。内容精炼实用,适合快速入门Django全栈开发。
378 1
|
8月前
|
缓存 前端开发 应用服务中间件
Web端实时通信技术SSE在携程机票业务中的实践应用
本文介绍了携程机票前端基于Server-Sent Events(SSE)实现服务端推送的企业级全链路通用技术解决方案。文章深入探讨了 SSE 技术在应用过程中包括方案对比、技术选型、链路层优化以及实际效果等多维度的技术细节,为类似使用场景提供普适性参考和借鉴。该方案设计目标是实现通用性,适用于各种网络架构和业务场景。
256 1