Django 中间件(Middleware)详解

Django 的中间件(Middleware)是一个轻量级的、底层的插件系统,它可以在 Django 的请求和响应处理过程中插入自定义逻辑。中间件是 Django 框架的重要组成部分,允许开发者在请求到达视图之前或响应返回客户端之前对数据进行处理。


什么是 Middleware?

Middleware 是一个类,它可以对 Django 的请求和响应进行拦截和处理。它的主要作用是:

  • 在请求到达视图之前,进行预处理。
  • 在响应返回客户端之前,进行后处理。

Middleware 是 Django 框架的钩子系统,允许开发者在请求和响应的生命周期中插入自定义逻辑。


Middleware 的工作流程

  1. 请求阶段

    • 当客户端发起请求时,Django 会按 MIDDLEWARE 列表的顺序依次调用每个中间件的 process_request__call__ 方法。
    • 中间件可以修改请求对象,或者直接返回响应(阻止后续中间件和视图的执行)。
  2. 视图阶段

    • 请求通过所有中间件后,进入视图函数处理。
  3. 响应阶段

    • 视图函数返回响应后,Django 会按 MIDDLEWARE 列表的逆序 依次调用每个中间件的 process_response 方法。
    • 中间件可以修改响应对象,或者直接返回新的响应。

Middleware 的常见用途

  1. 安全性
    • 强制 HTTPS、设置安全头等。
  2. 会话管理
    • 管理用户的登录状态和会话。
  3. 权限控制
    • 检查用户是否有权限访问某些页面。
  4. 性能监控
    • 记录请求的处理时间。
  5. 日志记录
    • 记录请求和响应的详细信息。
  6. 全局异常处理
    • 捕获未处理的异常并记录日志。

默认中间件

Django 默认提供了一些常用的中间件,配置在 settings.pyMIDDLEWARE 列表中:

python 复制代码
MIDDLEWARE = [
    "django.middleware.security.SecurityMiddleware",  # 提供安全相关功能
    "django.contrib.sessions.middleware.SessionMiddleware",  # 管理用户会话
    "django.middleware.common.CommonMiddleware",  # 提供通用功能
    "django.middleware.csrf.CsrfViewMiddleware",  # 防止跨站请求伪造
    "django.contrib.auth.middleware.AuthenticationMiddleware",  # 绑定用户到 request.user
    "django.contrib.messages.middleware.MessageMiddleware",  # 支持消息框架
    "django.middleware.clickjacking.XFrameOptionsMiddleware",  # 防止点击劫持
]

自定义 Middleware

1. 创建自定义 Middleware

以下是一个记录请求处理时间的性能监控中间件示例:

python 复制代码
import time
import logging

logger = logging.getLogger(__name__)

class PerformanceMonitoringMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        # 请求开始时间
        start_time = time.time()

        # 处理请求
        response = self.get_response(request)

        # 请求结束时间
        end_time = time.time()
        duration = end_time - start_time

        # 记录性能日志
        logger.info(
            f"Performance: {request.method} {request.path} took {duration:.2f} seconds"
        )

        return response

2. 注册自定义 Middleware

settings.pyMIDDLEWARE 列表中添加自定义中间件:

python 复制代码
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",
    "real_estate.middleware.PerformanceMonitoringMiddleware",  # 自定义中间件
]

3. 测试自定义 Middleware

启动 Django 开发服务器,访问任意页面,查看日志输出:

bash 复制代码
python manage.py runserver

日志输出示例:

vbnet 复制代码
INFO:real_estate.middleware:Performance: GET /real_estate/ took 0.12 seconds
INFO:real_estate.middleware:Performance: POST /real_estate/add/ took 0.45 seconds

Middleware 的生命周期方法

一个完整的中间件可以实现以下方法:

  1. __init__(self, get_response)

    • 初始化中间件。
    • get_response 是一个可调用对象,用于处理请求。
  2. __call__(self, request)

    • 处理请求和响应。
    • 必须返回一个 HttpResponse 对象。
  3. process_view(self, request, view_func, view_args, view_kwargs)(可选):

    • 在视图函数调用之前执行。
    • 可以返回 None(继续处理)或 HttpResponse(中断处理)。
  4. process_exception(self, request, exception)(可选):

    • 捕获视图函数中未处理的异常。
    • 可以返回 HttpResponse(替代默认的异常处理)。
  5. process_template_response(self, request, response)(可选):

    • 在模板渲染之前执行。
    • 必须返回一个 TemplateResponse 对象。

更多自定义 Middleware 示例

1. IP 黑名单

阻止特定 IP 地址访问网站:

python 复制代码
from django.http import HttpResponseForbidden

class BlockIPMiddleware:
    BLOCKED_IPS = ["192.168.1.100", "10.0.0.1"]

    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        ip = request.META.get("REMOTE_ADDR")
        if ip in self.BLOCKED_IPS:
            return HttpResponseForbidden("Forbidden: Your IP is blocked.")
        return self.get_response(request)

2. 自定义响应头

为所有响应添加自定义 HTTP 头:

python 复制代码
class CustomHeaderMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        response = self.get_response(request)
        response["X-Custom-Header"] = "MyCustomHeaderValue"
        return response

3. 动态语言切换

根据请求头设置语言:

python 复制代码
from django.utils.translation import activate

class LanguageMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        language = request.GET.get("lang", "en")
        activate(language)
        return self.get_response(request)

总结

  • Middleware 是 Django 的钩子系统,允许开发者在请求和响应的生命周期中插入自定义逻辑。
  • 默认中间件提供了安全性、会话管理、CSRF 防护等功能。
  • 自定义中间件可以实现日志记录、性能监控、权限控制等功能。
  • 中间件的顺序很重要,影响请求和响应的处理流程。

通过合理使用中间件,可以极大地增强 Django 应用的功能和灵活性!

Similar code found with 1 license type

相关推荐
wxin_VXbishe10 小时前
springboot居家养老管理系统-计算机毕业设计源码55953
java·c++·spring boot·python·spring·django·php
互亿无线明明10 小时前
国际金融短信:如何为跨境金融业务构建稳定安全的消息通知链路?
java·python·安全·eclipse·django·virtualenv·pygame
计算机徐师兄12 小时前
Python基于Django的MOOC线上课程推荐数据分析与可视化系统(附源码,文档说明)
python·数据分析·django·慕课线上课程推荐·慕课线上课程推荐可视化系统·pytho线上课程推荐可视化·线上课程推荐数据分析可视化系统
Sammyyyyy18 小时前
Django 6.0 发布,新增原生任务队列与 CSP 支持
数据库·后端·python·django·sqlite·servbay
高洁0118 小时前
智能体大模型时代的AI革新者
人工智能·深度学习·算法·机器学习·django
JAVA+C语言18 小时前
Python+Django 核心介绍
开发语言·python·django
qq_229058012 天前
运行djando项目 配置启动类 label_studio包含前后端启动方法
python·django
码界奇点2 天前
基于Python与Django的白泽自动化运维系统设计与实现
运维·python·django·毕业设计·源代码管理
计算机毕业编程指导师2 天前
【Python大数据选题】基于Spark+Django的电影评分人气数据可视化分析系统源码 毕业设计 选题推荐 毕设选题 数据分析 机器学习
大数据·hadoop·python·计算机·spark·django·电影评分人气
Python极客之家2 天前
基于Django的高校二手市场与社交系统
后端·python·数据挖掘·django·毕业设计