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

相关推荐
数据知道14 小时前
Django基础项目:从零到一搭建用户管理系统
python·django·python web·python项目
wa的一声哭了15 小时前
并行计算 PCAM方法学
linux·运维·服务器·arm开发·python·spring·django
凤凰战士芭比Q1 天前
Linux部署基于Django的博客系统
linux·运维·django
1***s6321 天前
MySQLGraphQL案例
django·hbase·图形洹染
S***q1921 天前
PythonGraphQLAPI
zookeeper·django·houdini
云栈开源日记2 天前
Python 开发技术栈梳理:从数据库、爬虫到 Django 与机器学习
数据库·爬虫·python·学习·机器学习·django
Warren982 天前
软件测试常见面试题
linux·python·django·flask·virtualenv·pygame·tornado
空影星2 天前
ValiDrive:一键验证USB真实容量
python·智能手机·django·flask
不知更鸟2 天前
无法联系上下文
python·django