全书目录

第十四篇:Django 完全指南 —— 中央行政城区宇宙

第七章:ORM —— 档案员如何查卷宗,而不是手写 SQL 大字报

1 分钟 338 字 第 281 / 962 个阅读单元

Django ORM 是很多人真正留下来的原因之一。

它让你像指挥档案员一样查询数据:

py
from .models import Permit

permit = Permit.objects.create(
    title="跨区施工许可",
    department="建设处",
    description="申请夜间施工",
    created_by=request.user,
)

pending_qs = Permit.objects.filter(status=Permit.Status.PENDING)

permit = Permit.objects.get(pk=18)

permit = Permit.objects.filter(pk=18).first()

Permit.objects.filter(pk=18).update(status=Permit.Status.APPROVED)

最关键的概念,是 QuerySet 惰性执行

text
Permit.objects.filter(...)
    .select_related("created_by")
    .order_by("-created_at")

上面这串通常还没真正打数据库。

真正执行往往发生在这些时刻:

  • 你开始 for 遍历
  • 你切片取值
  • list(...)
  • get() / first() / exists()
  • 模板开始渲染它

这会直接影响性能判断。

比如列表页中常见的 N+1 问题:

py
permits = Permit.objects.all()

模板里如果每行都访问 permit.created_by.username,就可能额外查很多次。更稳的写法:

py
permits = Permit.objects.select_related("created_by").all()

可以把 ORM 查卷宗理解成这样:

text
你发出查档指令
    │
    ▼
QuerySet 先记下“要查什么”
    │
    ▼
等真正需要结果时才执行 SQL
    │
    ▼
把结果映射成 Python 对象

所以 ORM 不是“不会 SQL 的替代品”。

更准确地说:

ORM 帮你用更高层的方式组织数据库交互;懂 SQL 会让你更会用 ORM。