Django ORM 的完整工作流程涵盖 模型构建、查询执行、数据库交互 和 结果映射 四大阶段。以下是详细解析,包含了你之前提到的 Model 构建阶段:
一、模型构建阶段(Model Construction)
1. 元类解析模型结构
- 核心元类:
django.db.models.base.ModelBase
- 关键步骤:
- 解析字段:遍历模型类属性,提取
Field
子类(如CharField
、ForeignKey
)。 - 生成元数据:创建
Options
类,存储db_table
、indexes
等元信息。 - 建立关系:处理
ForeignKey
、ManyToManyField
,生成反向关联描述。 - 注册模型:将模型类注册到
django.apps.apps
注册表。
- 解析字段:遍历模型类属性,提取
2. 字段与数据库类型映射
- 示例映射:
class Book(models.Model): title = models.CharField(max_length=100) # VARCHAR(100) price = models.DecimalField(max_digits=5, decimal_places=2) # DECIMAL(5,2) published_date = models.DateField() # DATE
3. 验证模型完整性
- Django 启动时(或执行
makemigrations
)验证:- 字段参数合法性(如
max_length
必须为整数)。 - 关联关系一致性(如确保关联模型存在)。
- 字段参数合法性(如
二、查询执行阶段(Query Execution)
1. 查询集创建与链式操作
- 核心类:
django.db.models.query.QuerySet
- 惰性特性:
# 未执行 SQL queryset = Book.objects.filter(author="Doubao").order_by("-price") # 表达式树结构: # Query { # model: Book, # where: [AND, =(author, "Doubao")], # order_by: ["-price"] # }
2. 查询表达式树构建
- 核心组件:
WhereNode
:存储过滤条件。OrderBy
:存储排序规则。Annotation
:存储聚合逻辑(如Count('reviews')
)。
三、数据库交互阶段(Database Interaction)
1. SQL 生成与编译
- 核心类:
django.db.backends.*.compiler.SQLCompiler
- 关键步骤:
- 解析查询树:将
WhereNode
转换为 SQLWHERE
子句。 - 处理 JOIN:自动生成关联查询的
JOIN
语句。 - 参数化查询:动态值使用占位符(如
%s
)。
- 解析查询树:将
# Python 查询
books = Book.objects.filter(author="Doubao", price__gt=50)
# 生成的 SQL(PostgreSQL 示例)
SELECT "books"."id", "books"."title", "books"."author", "books"."price"
FROM "books"
WHERE ("books"."author" = %s AND "books"."price" > %s);
# 参数:['Doubao', 50.0]
2. 数据库连接与执行
- 核心类:
django.db.backends.*.base.DatabaseWrapper
- 连接管理:
- 默认每次请求创建新连接,请求结束后关闭。
- 支持第三方连接池(如
django - db - connection - pool
)。
3. 事务处理
- 自动提交模式:默认每条 SQL 作为独立事务。
- 显式事务:通过
@transaction.atomic
管理事务边界。
四、结果映射阶段(Result Mapping)
1. 数据库结果解析
- 核心类:
django.db.models.loading.ModelLoader
- 关键步骤:
- 将数据库行数据(元组)映射到模型字段。
- 处理关联字段:
- 立即加载:通过
select_related()
执行 JOIN 查询。 - 延迟加载:通过
prefetch_related()
执行子查询。
- 立即加载:通过
2. 对象实例化与缓存
- 实例化流程:
# 数据库返回:(1, "Python Crash Course", "Doubao", 99.99) # 转换为模型对象: book = Book(id=1, title="Python Crash Course", author="Doubao", price=99.99)
- 缓存机制:
QuerySet
首次求值后缓存结果(_result_cache
)。- 重复访问同一
QuerySet
直接返回缓存。
五、完整工作流程图解
1. 模型构建阶段 2. 查询执行阶段 3. 数据库交互阶段 4. 结果映射阶段
─────────────────┐ ────────────────────┐ ────────────────────┐ ───────────────────
│ │ │ │
定义模型类 │ │ │ │
↓ │ │ │ │
元类解析字段 │ │ │ │
↓ │ │ │ │
生成元数据 │ │ │ │
↓ │ │ │ │
注册模型 │ 创建查询集 │ │ │
│ ↓ │ │ │
│ 添加过滤/排序条件 │ │ │
│ ↓ │ │ │
│ 触发 SQL 执行 │ 生成 SQL 语句 │ │
├──────────────────────────> │ ↓ │ │
│ │ 获取数据库连接 │ │
│ │ ↓ │ │
│ │ 执行 SQL │ 解析结果集 │
│ │ └─────────────────────────> │ ↓ │
│ │ │ 实例化模型对象 │
│ │ │ ↓ │
│ │ │ 应用缓存策略 │
│ │ │ ↓ │
│ │ │ 返回结果集 │
│ │ │ │
六、关键优化点
减少查询次数:
- 使用
select_related()
处理一对一/外键关联(JOIN 查询)。 - 使用
prefetch_related()
处理多对多/反向关联(子查询)。
- 使用
避免全表扫描:
- 通过
Meta.indexes
为高频查询字段添加索引。 - 使用
filter()
代替all()
缩小结果集。
- 通过
优化数据提取:
- 使用
values()
/values_list()
直接返回字典/元组。 - 使用
only()
/defer()
只加载需要的字段。
- 使用