Django 完整生命周期分析
本文基于 Django 3.1.6 源码,探讨了从 HTTP 请求到达至响应返回客户端的整个过程,以及在此过程中数据库连接的管理机制。
一、Django 完整生命周期概览
- HTTP 请求生命周期(Request → Response)
展示了从接收请求到生成响应的全过程。
┌───────────────────────────────┐
│ Web Server(Nginx) │
└───────────────┬───────────────┘
│
▼
┌───────────────────────────────┐
│ WSGI Server(Gunicorn) │
└───────────────┬───────────────┘
│env
▼
┌───────────────────────────────┐
│ Django WSGIHandler │
│ (django.core.handlers.wsgi) │
└───────────────┬───────────────┘
│构建Request对象
▼
┌──────────────────────────────────────────┐
│ 中间件(process_request) │
│ M1 → M2 → ... → Mn │
└───────────────┬──────────────────────────┘
│匹配 URL
▼
┌───────────────────────────────┐
│ URL Resolver │
└───────────────┬───────────────┘
│路由到视图
▼
┌───────────────────────────────┐
│ 视图 │
│ 打开数据库连接(懒加载) │
│ 执行业务逻辑 │
└───────────────┬───────────────┘
│生成 Response
▼
┌──────────────────────────────────────────┐
│ 中间件(process_response) │
│ Mn → ... → M2 → M1 │
└───────────────┬──────────────────────────┘
│处理异常/模板渲染
▼
┌───────────────────────────────┐
│ WSGIHandler 返回响应 │
└───────────────┬───────────────┘
│
▼
┌───────────────────────────────┐
│ Gunicorn → Nginx → 客户端 │
└───────────────────────────────┘
- 数据库连接生命周期(懒加载 + 自动管理)
描述了数据库连接的懒加载特性和自动管理方式。
请求开始
│
│(没有数据库连接,Lazy)
▼
视图第一次触发 ORM 查询
│
▼
ensure_connection() 建立连接
│
│
▼
请求期间复用同一连接
│
▼
请求结束 → close_if_unusable_or_obsolete()
│
├── CONN_MAX_AGE = 0 → 立即关闭
│
├── CONN_MAX_AGE > 0 → 存活一段时间
│
└── CONN_MAX_AGE = None → 长连接
二、生命周期详细解析
1. WSGI 启动阶段
入口文件和核心类定义了如何处理请求。
django/core/handlers/wsgi.py
class WSGIHandler(BaseHandler):
def __call__(self, environ, start_response):
request = WSGIRequest(environ)
response = self.get_response(request)
- 创建 WSGIRequest 对象
- 加载所有中间件
- 数据库连接对象已创建,但未实际连接数据库
2. BaseHandler.get_response()
这是生命周期中的核心调度方法。
django/core/handlers/base.py
load middleware
↓
process_request()
↓
URL resolver
↓
view函数
↓
process_response()
↓
异常处理
↓
返回 Response
3. 中间件(Middleware)执行顺序
Django 按照特定顺序执行中间件,形成洋葱模型。
M1.process_request
M2.process_request
M3.process_request
...
M3.process_response
M2.process_response
M1.process_response
4. URL 路由解析 (URL Resolver)
负责将 URL 匹配到对应的视图函数,并传递必要的参数。
django/urls/resolvers.py
URLResolver.resolve()
5. 视图(View)执行
视图执行时首次与数据库交互。
三、数据库连接管理
Django 使用懒加载技术来管理数据库连接。
1. 第一次访问数据库:cursor()
django/db/backends/base/base.py
def cursor(self):
self.ensure_connection()
return self._cursor()
def ensure_connection(self):
if self.connection is None:
self.connect()
确保在首次 ORM 操作时建立数据库连接。
2. 请求结束 → 连接自动回收
在请求结束后,Django 会根据配置自动管理数据库连接。
BaseHandler
CONN_MAX_AGE
根据不同的配置,连接可能在请求结束时立即关闭、超时关闭或保持长连接。
>0
None
四、异常处理流程
如果视图抛出异常,Django 会进行相应的处理。
视图抛异常
↓
process_exception(自下而上)
↓
exception middleware
↓
resolve 500 error handler
↓
生成 Response
五、模板渲染
当视图返回响应时,Django 在中间件层进行模板渲染。
TemplateResponse
response = response.render()
六、生命周期最终阶段
响应完成后,Django 将响应返回给 WSGI 服务器,并清理数据库连接。
七、完整流程图
客户端
│
▼
Nginx
│
▼
Gunicorn/uwsgi
│WSGI env
▼
Django WSGIHandler
│
├── 初始化中间件
│
▼
process_request() 中间件链
│
▼
URL Resolver(匹配路由)
│
▼
View 视图函数
│
├── 第一次 ORM 查询 → 打开数据库连接
│
├── 执行业务逻辑
│
▼
返回 Response
│
▼
process_response() 中间件链
│
▼
Django 回收数据库连接
│(根据 CONN_MAX_AGE)
▼
WSGI Server
│
▼
客户端
八、总结
| 阶段 |
行为 |
| WSGI 初始化 |
未建立数据库连接 |
| process_request |
仅处理请求,不访问数据库 |
| 视图第一次访问 ORM |
建立数据库连接(ensure_connection) |
| 视图期间 |
始终复用同一连接 |
| process_response |
产生最终响应 |
| 请求结束 |
根据 CONN_MAX_AGE 自动管理连接 |
| CONN_MAX_AGE=None |
长连接,适合高性能服务 |
| 异步任务 |
必须手动 close_old_connections() |