Django 是一个功能完整的 Web 框架,从一个 HTTP
请求进入,到生成响应返回客户端,内部会经历一套非常完整且可扩展的生命周期流程。
本文以 Django 3.1.6 源码 为参照,从最底层的 WSGI Handler
开始,逐步解析:
- 请求是如何进入 Django 的
- 中间件如何链式执行
- 视图如何被调度
- ORM 是何时第一次打开数据库连接
- 异常、响应如何处理
- Django 如何自动管理数据库连接
并给出 全链路流程图(请求流程 + 数据库连接生命周期)。
一、Django 完整生命周期总览(流程图)
1. 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 → 客户端 │
└───────────────────────────────┘
2. 数据库连接生命周期(懒加载 + 自动管理)
请求开始
│
│(没有数据库连接,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
核心类:
python
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
这是一个典型的 洋葱模型(Onion Model)
4. URL 路由解析 (URL Resolver)
文件:django/urls/resolvers.py
URLResolver.resolve():
- 匹配 URL\
- 找到对应 View\
- 把路由参数注入
5. 视图(View)执行
视图执行期间才会第一次访问数据库。
三、数据库连接是怎么管理的?
Django 采用 Lazy Connection(懒加载)。
只要你的代码没有执行 SQL,数据库连接压根不会建立。
1. 第一次访问数据库:cursor()
入口:django/db/backends/base/base.py
python
def cursor(self):
self.ensure_connection()
return self._cursor()
ensure_connection()
python
def ensure_connection(self):
if self.connection is None:
self.connect()
➡ 第一次 ORM 操作时才真正创建连接。
2. 请求结束 → 连接自动回收
在 BaseHandler 的 finally 中:
python
for db in connections.all():
db.close_if_unusable_or_obsolete()
最终根据 CONN_MAX_AGE 判断是否关闭:
0→ 请求结束立即关闭(默认行为)\>0→ 超时关闭\None→ 长连接(不自动关闭)
四、异常处理流程
如果视图抛异常:
视图抛异常
↓
process_exception(自下而上)
↓
exception middleware
↓
resolve 500 error handler
↓
生成 Response
五、模板渲染
视图返回 TemplateResponse 时:
Django 会在中间件层执行 response = response.render()。
六、生命周期最终阶段
完成响应后:
- response 返回给 WSGI server\
- Django 清理数据库连接(根据 CONN_MAX_AGE)\
- 本次请求生命周期结束
七、完整流程图
客户端
│
▼
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()