0

0

Django中的中间件(Middleware)是什么?

狼影

狼影

发布时间:2025-09-05 23:09:03

|

541人浏览过

|

来源于php中文网

原创

Django中间件在请求响应周期中扮演核心角色,它作为请求与响应的拦截器,在process_request、process_view、process_response等方法中实现认证、日志、限流等横切功能,通过MIDDLEWARE列表按序执行,支持短路逻辑与异常处理,提升代码复用性与系统可维护性。

django中的中间件(middleware)是什么?

Django中的中间件(Middleware),简单来说,它就像是你在一个复杂的生产线上,为每个产品(请求或响应)定制的检查站、加工点或者质量控制环节。它允许你在请求到达视图函数之前,以及视图函数处理完生成响应之后,对这些请求和响应进行拦截、修改或增强。它提供了一种非常灵活的方式来全局性地处理应用中的一些横切关注点,比如认证、会话管理、内容压缩、CORS策略等等,而无需在每个视图函数中重复编写这些逻辑。

解决方案

Django的中间件机制,本质上是一系列轻量级的、可插拔的组件,它们形成一个链条,在请求-响应周期中顺序执行。当你向Django应用发送一个请求时,这个请求会从

MIDDLEWARE
设置中定义的第一个中间件开始,依次经过每个中间件的
process_request
方法,然后到达URL解析器和视图函数。视图函数处理完毕生成响应后,这个响应会反向地、依次经过每个中间件的
process_response
方法,最终返回给客户端。这种双向流动的处理模式,正是中间件强大之处的核心。它让你可以在不修改核心业务逻辑的前提下,在系统的边缘地带“注入”各种功能。

Django中间件究竟在请求响应周期中扮演什么角色?

要理解中间件,就得把它放到Django的整个请求-响应生命周期里看。这东西,在我看来,就是Django架构里那些“幕后英雄”之一。当一个HTTP请求涌入你的Django应用,它并不是直接冲到你写的那个处理业务逻辑的

views.py
里。不,它得先过一道道“关卡”,这些关卡就是中间件。

具体来说,一个中间件类可以实现几个特殊的方法,这些方法会在请求的不同阶段被Django调用:

  • process_request(self, request)
    : 这是请求刚进来时最先被调用的方法之一。你可以在这里对
    request
    对象做任何预处理,比如检查用户是否登录、添加一些自定义信息到
    request
    对象上。如果这个方法返回一个
    HttpResponse
    对象,那么整个请求处理流程就此打住,这个响应会直接返回给客户端,后面的中间件和视图都不会再执行了。这对于实现一些短路逻辑(比如未认证用户的重定向)非常有用。
  • process_view(self, request, view_func, view_args, view_kwargs)
    : 在URL解析完毕,确定了要调用哪个视图函数之后,但在视图函数实际执行之前,这个方法会被调用。你可以在这里对视图函数进行一些前置检查,比如权限验证,或者修改传递给视图的参数。同样,如果它返回一个
    HttpResponse
    ,视图就不会执行。
  • process_template_response(self, request, response)
    : 这个方法稍微特殊一点,它只对那些返回
    TemplateResponse
    或其子类的视图响应起作用。它允许你在模板渲染之前,或者渲染过程中对
    TemplateResponse
    对象进行修改。
  • process_response(self, request, response)
    : 当视图函数执行完毕,生成了一个
    HttpResponse
    对象之后,这个响应会反向地、依次经过之前所有中间件的这个方法。这是你修改响应的最后机会,比如添加HTTP头、压缩内容、设置cookie等。这个方法必须返回一个
    HttpResponse
    对象。
  • process_exception(self, request, exception)
    : 如果在视图函数或者之前的任何一个中间件中抛出了异常,这个方法就会被调用。你可以在这里捕获并处理异常,比如记录错误日志,或者返回一个友好的错误页面。如果它返回一个
    HttpResponse
    ,那么异常就被“消化”了,这个响应会返回给客户端。

理解这些方法以及它们的执行顺序和返回值行为,是玩转Django中间件的关键。它们就像一个个精密的小齿轮,共同驱动着整个应用的请求响应流程。

自定义一个Django中间件难不难?有哪些常见陷阱?

自定义一个Django中间件,从代码结构上看,其实并不复杂。你只需要创建一个Python类,并在其中实现你想要拦截的那些

process_
方法就行。核心思路就是:写一个类,然后把它添加到
settings.py
MIDDLEWARE
列表里。

天工大模型
天工大模型

中国首个对标ChatGPT的双千亿级大语言模型

下载
# myapp/middleware.py
from django.http import HttpResponse

class MyCustomMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response
        # 这里可以做一些一次性的初始化操作

    def __call__(self, request):
        # 请求到达视图之前
        # print("请求进入 MyCustomMiddleware")
        # 可以在这里修改 request 对象
        # request.my_custom_data = "Hello from middleware!"

        response = self.get_response(request) # 将请求传递给下一个中间件或视图

        # 视图处理完,响应返回之前
        # print("响应离开 MyCustomMiddleware")
        # 可以在这里修改 response 对象
        # response['X-My-Header'] = 'Custom Value'
        return response

    def process_view(self, request, view_func, view_args, view_kwargs):
        # print(f"即将调用视图: {view_func.__name__}")
        # 可以在这里做一些视图执行前的检查
        # if not request.user.is_authenticated:
        #     return HttpResponse("Unauthorized", status=401)
        return None # 返回None表示继续执行下一个中间件或视图

然后,在你的

settings.py
里,把这个中间件加进去:

# 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',
    'myapp.middleware.MyCustomMiddleware', # 添加你的自定义中间件
]

看起来挺简单对吧?但实际操作中,还是有些坑需要注意:

  1. 中间件的顺序至关重要! 这是最容易犯错的地方。
    MIDDLEWARE
    列表的顺序决定了中间件的执行顺序。
    process_request
    是自上而下执行,而
    process_response
    则是自下而上执行。比如,如果你想在认证之后才检查权限,那么你的权限中间件就必须放在
    AuthenticationMiddleware
    之后。顺序错了,逻辑就全乱套了。
  2. __init__
    方法只执行一次。
    它的参数
    get_response
    是一个可调用对象,代表了中间件链条中的下一个环节。你应该把它保存起来,并在
    __call__
    方法中调用它来传递请求。
  3. 返回值的问题。
    process_request
    process_view
    process_exception
    方法如果返回
    None
    ,意味着请求会继续传递给下一个中间件或视图。但如果它们返回了一个
    HttpResponse
    对象,那么整个请求处理流程就会短路,直接将这个响应返回给客户端。而
    process_response
    方法则必须返回一个
    HttpResponse
    对象。搞混了这些,你的应用可能就会出现意想不到的行为。
  4. 性能考量。 中间件会处理每一个请求,所以如果你的中间件做了很多耗时的操作,比如复杂的数据库查询或外部API调用,那会严重拖慢整个应用的响应速度。务必保持中间件的轻量和高效。
  5. 调试难度。 当中间件链条很长时,排查问题可能会比较头疼。我通常会在关键的
    process_
    方法里加一些
    print
    语句或者日志输出,来追踪请求和响应的流向,看它到底在哪一步出了问题。

除了Django自带的,还有哪些场景适合用中间件解决?

Django自带的中间件已经覆盖了很多基础功能,比如会话、认证、CSRF保护等。但中间件的真正威力在于它能让你为应用定制各种横切关注点。在我看来,任何需要在请求进入视图前或响应离开视图后进行统一处理的逻辑,都是中间件的绝佳用武之地。

  • 自定义认证/授权逻辑: 尽管Django有
    AuthenticationMiddleware
    ,但如果你需要更复杂的认证流程(比如基于JWT、OAuth2,或者多因素认证),或者细粒度的基于角色的访问控制,自定义中间件可以帮你统一处理,而不用在每个视图里写
    @permission_required
    。你可以在
    process_request
    里解析token,把用户信息附加到
    request.user
    上。
  • 请求/响应日志记录: 想要记录每个请求的IP、URL、耗时,以及每个响应的状态码、大小?一个日志中间件可以在
    process_request
    里记录请求开始时间,然后在
    process_response
    里计算耗时,并把所有信息写入日志。
  • API限流(Rate Limiting): 对于公共API,为了防止恶意请求或资源滥用,限流是必不可少的。你可以在
    process_request
    里检查请求的来源IP或用户ID,结合缓存系统(如Redis)来限制在一定时间内的请求次数。如果超出限制,直接返回
    429 Too Many Requests
  • 内容压缩/解压缩: 如果你的应用需要处理大量文本数据,你可以在
    process_response
    里对响应内容进行Gzip压缩,或者在
    process_request
    里解压缩传入的请求体。这能有效减少网络传输量。
  • 安全头部注入: 比如为所有响应自动添加
    X-Content-Type-Options
    ,
    X-Frame-Options
    ,
    Strict-Transport-Security
    等安全相关的HTTP头部,这对于提升网站安全性非常重要。
  • 维护模式/灰度发布: 当你需要部署更新或进行系统维护时,可以启用一个维护模式中间件,让所有请求都重定向到一个维护页面,或者只允许特定IP访问。对于灰度发布,你可以在中间件里根据用户ID或请求头,将一部分用户流量路由到新版本,其余用户继续使用旧版本。
  • 统一错误处理: 尽管
    process_exception
    可以处理异常,但你也可以构建一个更通用的错误处理中间件,将所有未捕获的异常统一格式化为JSON错误响应,或者重定向到自定义的错误页面,而不是让Django显示默认的调试信息。

在我看来,中间件的价值在于它提供了一种“非侵入式”的扩展能力。它让你的核心业务逻辑保持干净,而那些通用的、横向的功能则可以优雅地抽离出来,集中管理。这不仅提高了代码的可维护性,也让整个系统架构更加清晰。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
Python Web 框架 Django 深度开发
Python Web 框架 Django 深度开发

本专题系统讲解 Python Django 框架的核心功能与进阶开发技巧,包括 Django 项目结构、数据库模型与迁移、视图与模板渲染、表单与认证管理、RESTful API 开发、Django 中间件与缓存优化、部署与性能调优。通过实战案例,帮助学习者掌握 使用 Django 快速构建功能全面的 Web 应用与全栈开发能力。

166

2026.02.04

什么是中间件
什么是中间件

中间件是一种软件组件,充当不兼容组件之间的桥梁,提供额外服务,例如集成异构系统、提供常用服务、提高应用程序性能,以及简化应用程序开发。想了解更多中间件的相关内容,可以阅读本专题下面的文章。

183

2024.05.11

Golang 中间件开发与微服务架构
Golang 中间件开发与微服务架构

本专题系统讲解 Golang 在微服务架构中的中间件开发,包括日志处理、限流与熔断、认证与授权、服务监控、API 网关设计等常见中间件功能的实现。通过实战项目,帮助开发者理解如何使用 Go 编写高效、可扩展的中间件组件,并在微服务环境中进行灵活部署与管理。

226

2025.12.18

json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

457

2023.08.07

json是什么
json是什么

JSON是一种轻量级的数据交换格式,具有简洁、易读、跨平台和语言的特点,JSON数据是通过键值对的方式进行组织,其中键是字符串,值可以是字符串、数值、布尔值、数组、对象或者null,在Web开发、数据交换和配置文件等方面得到广泛应用。本专题为大家提供json相关的文章、下载、课程内容,供大家免费下载体验。

547

2023.08.23

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

335

2023.10.13

go语言处理json数据方法
go语言处理json数据方法

本专题整合了go语言中处理json数据方法,阅读专题下面的文章了解更多详细内容。

82

2025.09.10

python中print函数的用法
python中print函数的用法

python中print函数的语法是“print(value1, value2, ..., sep=' ', end=' ', file=sys.stdout, flush=False)”。本专题为大家提供print相关的文章、下载、课程内容,供大家免费下载体验。

192

2023.09.27

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

76

2026.03.11

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 22.5万人学习

Django 教程
Django 教程

共28课时 | 5万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号