应先判断request.user.is_authenticated,再取user_id等字段;日志需记录用户id(或none)、路径、方法、ip、ua和状态码;须在process_response中写库,避免同步阻塞。

Middleware中如何获取当前登录用户
没登录的请求 request.user 是 AnonymousUser 实例,直接调用 request.user.id 会报 AttributeError。必须先判断是否认证通过:
if request.user.is_authenticated:才能安全取
request.user.id、request.user.username 等字段。Django 4.2+ 的 AuthenticationMiddleware 必须在自定义中间件之前加载,否则 request.user 始终为匿名对象。记录日志时该捕获哪些关键字段
只记 URL 和时间远远不够。真实排障需要知道「谁、什么时候、从哪台设备、做了什么」:
-
user_id(或None表示未登录) -
path(request.path,不含 GET 参数) -
method(request.method,如POST) -
ip_address(从request.META.get('HTTP_X_FORWARDED_FOR') or request.META.get('REMOTE_ADDR')取,注意代理场景) -
user_agent(request.META.get('HTTP_USER_AGENT', '')[:200],截断防超长) -
status_code(需在process_response中拿到,不能在process_request里写)
为什么不能在 process_request 里保存日志到数据库
因为此时响应还没生成,status_code 未知,且如果视图抛出异常,process_request 已执行但 process_response 不会触发,导致日志缺失或状态错乱。正确做法是:
Python 3.14.2是Python编程语言在2025年12月5日发布的稳定版本,属于3.14系列的第二个维护更新。该版本包含了18项修复,重点解决了多进程、数据类及正则表达式等模块的回归问题,并修复了CVE-2025-12084等安全漏洞。此版本标志着自由线程模式(移除GIL)正式获得官方支持,是Python发展的重要里程碑。
- 在
process_request中只做轻量准备(如提取 IP、UA、用户 ID),存入request._log_data = {...} - 在
process_response中补全status_code,再调用LogEntry.objects.create(...) - 同时实现
process_exception,捕获未处理异常时也写一条status_code=500的日志
save() 同步写库,尤其高并发下容易拖慢整个请求链路;考虑用 bulk_create 缓存一批再刷,或扔进 Celery。Django 5.0+ 中中间件类写法变化带来的兼容问题
新版本要求中间件必须是可调用对象,推荐写成类并实现 __call__ 方法,而不是老式的 process_request 钩子函数:
class LoggingMiddleware:<br> def __init__(self, get_response):<br> self.get_response = get_response<br><br> def __call__(self, request):<br> # 在这里做 request 阶段逻辑<br> response = self.get_response(request)<br> # 在这里做 response 阶段逻辑,response.status_code 可用<br> return response旧写法(带
process_* 方法的类)在 Django 5.0+ 仍可用,但会被警告;若项目已升级,务必检查 MIDDLEWARE 配置里有没有漏掉 'django.contrib.auth.middleware.AuthenticationMiddleware' —— 它缺失会导致 request.user 永远是匿名用户。实际部署时最容易被忽略的是数据库连接池压力:每请求都写日志,可能瞬间打满连接数。建议加个开关配置(如 LOGGING_MIDDLEWARE_ENABLED = True),开发/测试环境开,生产环境按需开启特定路径(如仅记录 /api/ 下的操作),或者把日志先写到 Redis 再异步落库。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










