django中间件说明

devtools/2025/3/14 14:33:32/

Django中间件是一种在请求和响应处理过程中介入的机制,允许你在视图处理请求之前或之后执行自定义代码。中间件适用于处理全局性任务,如身份验证、日志记录、内容修改等。以下是Django中间件的详细说明和使用方法:


一、中间件的核心概念

  1. 作用阶段
    请求阶段:在路由到视图之前处理请求(如身份验证)。
    视图阶段:在调用视图前后执行操作(如权限检查)。
    响应阶段:在返回响应前修改内容(如添加HTTP头)。
    异常阶段:处理视图或中间件抛出的异常(如统一错误处理)。

  2. 中间件类方法
    process_request(request): 在路由到视图前调用。
    process_view(request, view_func, view_args, view_kwargs): 在视图被调用前执行。
    process_response(request, response): 在所有响应返回前处理。
    process_exception(request, exception): 处理视图抛出的异常。
    process_template_response(request, response): 处理模板响应(如修改上下文)。


二、创建自定义中间件

1. 编写中间件
python"># myapp/middleware/custom_middleware.py
import logging
from django.http import HttpResponseForbiddenlogger = logging.getLogger(__name__)class SimpleLoggingMiddleware:"""记录请求日志的中间件"""def __init__(self, get_response):self.get_response = get_responsedef __call__(self, request):# 请求处理前logger.info(f"Request started: {request.method} {request.path}")response = self.get_response(request)  # 继续处理链# 响应处理后logger.info(f"Request finished: {request.method} {request.path}{response.status_code}")return responseclass IPFilterMiddleware:"""过滤非法IP的中间件"""def __init__(self, get_response):self.get_response = get_responseself.allowed_ips = ['127.0.0.1', '192.168.1.0/24']  # 允许的IP或网段def __call__(self, request):client_ip = request.META.get('REMOTE_ADDR')if not self._is_ip_allowed(client_ip):return HttpResponseForbidden("IP地址被禁止访问")return self.get_response(request)def _is_ip_allowed(self, ip):# 简单示例:实际可能需要更复杂的IP检查逻辑return ip in self.allowed_ips
2. 配置中间件

settings.pyMIDDLEWARE 列表中注册中间件

python"># settings.py
MIDDLEWARE = ['django.middleware.security.SecurityMiddleware','django.contrib.sessions.middleware.SessionMiddleware','django.middleware.common.CommonMiddleware','django.middleware.csrf.CsrfViewMiddleware','myapp.middleware.custom_middleware.SimpleLoggingMiddleware',  # 自定义中间件'myapp.middleware.custom_middleware.IPFilterMiddleware',       # 另一个中间件
]

执行顺序
中间件按列表顺序从上到下处理请求(process_request)。
• 响应阶段按从下到上的顺序处理(process_response)。


三、中间件的常见应用场景

1. 请求日志记录

记录每个请求的路径、方法、耗时等信息:

python">class RequestTimingMiddleware:def __init__(self, get_response):self.get_response = get_responsedef __call__(self, request):start_time = time.time()response = self.get_response(request)duration = time.time() - start_timeprint(f"Request to {request.path} took {duration:.2f} seconds")return response
2. 用户认证增强

检查特定Header或Token:

python">class APITokenMiddleware:def __init__(self, get_response):self.get_response = get_responsedef __call__(self, request):if not request.user.is_authenticated:token = request.headers.get('Authorization', '').split('Bearer ')[-1]if token == 'SECRET_API_KEY':# 模拟用户登录(示例逻辑)request.user = get_user_model().objects.get(username='api_user')return self.get_response(request)
3. 跨域请求处理(CORS)

手动添加CORS头(或使用第三方库如 django-cors-headers):

python">class CustomCorsMiddleware:def __init__(self, get_response):self.get_response = get_responsedef __call__(self, request):response = self.get_response(request)response['Access-Control-Allow-Origin'] = '*'response['Access-Control-Allow-Methods'] = 'GET, POST, OPTIONS'response['Access-Control-Allow-Headers'] = 'Content-Type'return response
4. 响应内容修改

压缩响应或替换敏感信息:

python">import gzipclass GzipResponseMiddleware:def __init__(self, get_response):self.get_response = get_responsedef __call__(self, request):response = self.get_response(request)if 'gzip' in request.headers.get('Accept-Encoding', ''):response.content = gzip.compress(response.content)response['Content-Encoding'] = 'gzip'return response

四、中间件的注意事项

  1. 性能影响
    • 避免在中间件中执行耗时操作(如数据库查询),否则会拖慢所有请求。
    • 使用缓存优化频繁访问的数据(如用户权限信息)。

  2. 异常处理
    • 在 process_exception 中捕获异常时,需返回 None 以继续传递异常。
    • 生产环境中应记录错误日志而非暴露堆栈信息。

  3. 中间件顺序
    • 安全中间件(如 SecurityMiddleware)通常应放在最前面。
    • 依赖其他中间件的组件(如 SessionMiddleware 需在认证中间件之前)。

  4. 测试中间件
    • 使用Django测试客户端模拟请求,验证中间件行为:

    python">from django.test import RequestFactory, TestCaseclass TestMiddleware(TestCase):def test_ip_filter(self):factory = RequestFactory()request = factory.get('/', REMOTE_ADDR='192.168.1.5')middleware = IPFilterMiddleware(lambda r: None)response = middleware(request)self.assertEqual(response.status_code, 403)  # 假设该IP被禁止
    

五、中间件与其他组件的对比

组件用途作用范围
中间件全局请求/响应处理(如日志、认证)所有HTTP请求
信号(Signal)响应特定事件(如保存模型后触发操作)应用内部事件
上下文处理器向模板添加全局变量(如当前用户)模板渲染阶段

六、总结

Django中间件是处理HTTP请求和响应流程的核心机制,适用于以下场景:
全局功能:如日志、IP过滤、性能监控。
请求预处理:用户认证、数据解析。
响应后处理:修改响应头、压缩内容。
异常统一处理:记录错误、返回友好提示。

通过合理设计中间件,可以解耦代码并增强应用的可维护性。但需谨慎设计以避免性能瓶颈和逻辑混乱。


http://www.ppmy.cn/devtools/167044.html

相关文章

OSPF-2 邻接建立关系

上一期我们说了OSPF的邻居建立关系以及OSPF邻居关系建立中建立失败的因素以及相关实验案例 这一期我们来说说OSPF的邻接关系建立时需要交互哪些报文以及失败因素及原因和相关实验案例 一、概述 在运行了OSPF的网络当中为了交互链路状态信息和路由信息,互相之间需要建立邻接关…

Linux云计算SRE-第二十周

完成ELK综合案例里面的实验,搭建完整的环境 一、 1、安装nginx和filebeat,配置node0(10.0.0.100),node1(10.0.0.110),node2(10.0.0.120),采用filebeat收集nignx日志。 #node0、node1、node2采用以下相同方式收集ngin…

【 <一> 炼丹初探:JavaWeb 的起源与基础】之 JavaWeb 项目的部署:从开发环境到生产环境

<前文回顾> 点击此处查看 合集 https://blog.csdn.net/foyodesigner/category_12907601.html?fromshareblogcolumn&sharetypeblogcolumn&sharerId12907601&sharereferPC&sharesourceFoyoDesigner&sharefromfrom_link <今日更新> 一、开发环境…

Vue项目搜索引擎优化(SEO)终极指南:从原理到实战

文章目录 1. SEO基础与Vue项目的挑战1.1 为什么Vue项目需要特殊SEO处理&#xff1f;1.2 搜索引擎爬虫工作原理 2. 服务端渲染&#xff08;SSR&#xff09;解决方案2.1 Nuxt.js框架实战原理代码实现流程图 2.2 自定义SSR实现 3. 静态站点生成&#xff08;SSG&#xff09;技术3.1…

vue 知识点整理

1.data为什么是一个函数而不是对象 维度对象形式函数形式数据隔离性所有实例共享同一对象&#xff0c;导致数据污染每个实例拥有独立数据副本复用安全性不适用于可复用组件支持组件安全复用语言机制引用传递引发副作用函数返回值实现作用域隔离&#xff08;闭包&#xff09;框…

OpenCV(应用) —— 凸包检测的实战应用

文章目录 一、凸包的概念二、Opencv中的API三、应用场景与实战3.1、实战场景一一、凸包的概念 常见的找寻目标的外轮廓有矩形框(如最小外接矩阵)和圆形框,但这种包围框为了保持几何形状,与图形的真实轮廓贴合度较差。如果能找出图形最外层的端点,将这些端点连接起来,就可…

什么是SWAP虚拟内存?使用服务器如何开启SWAP虚拟内存

一、SWAP 虚拟内存是什么&#xff1f;‌ ‌定义‌&#xff1a; SWAP&#xff08;交换分区&#xff09;是磁盘上的一块空间&#xff0c;用于在物理内存&#xff08;RAM&#xff09;不足时&#xff0c;将部分不活跃的内存数据临时存储到磁盘中&#xff0c;避免系统因内存耗尽而崩…

AI+Mermaid 制作流程图

一、引言 在软件开发的全生命周期里&#xff0c;文档编写扮演着举足轻重的角色。它犹如项目的“导航图”&#xff0c;为团队成员清晰呈现项目架构、功能流程和技术细节&#xff0c;是保障高效协作的关键。然而&#xff0c;传统的文字描述往往难以直观地展现复杂的系统架构、业…