知其然,知其所以然
Django 2026-09-30

runserver 自动重载机制

实测 runserver 自动重载:默认 StatReloader;修改被导入的 .py 后 0.2–0.8 s 内新代码生效且进程被重启;修改模板不重启、缓存约 0.5 s 内刷新;没被导入的 .py 和非 .py 文件不触发重启。

Django runserver 自动重载 真实验证 动画演示
Django 2026-09-30

Django 系统检查框架

用自定义检查实测 Django 系统检查框架:Error 会阻止 check / migrate / runserver / test 等命令,Warning 默认只提示(--fail-level 可升级为失败);--tag 选择检查、SILENCED_SYSTEM_CHECKS 静音、check --deploy 在开发设置下报出 6 个警告。

Django 系统检查 check 真实验证 动画演示
Django 2026-09-30

QuerySet 的惰性执行与结果缓存

用查询捕获数出 QuerySet 每种操作发了几次查询:链式调用 0 次、第一次迭代 1 次并缓存;count / exists / [0] / bool / len / repr 各自的 SQL(repr 是 LIMIT 21);exists() 与 iterator() 不填充缓存;缓存会让同一个 QuerySet 看不到之后的新数据。

Django QuerySet 惰性 缓存 真实验证 动画演示
Django 2026-09-30

select_related() 与 prefetch_related() 查询对比

在 2000 本书 / 100 个作者 / 20 个标签上实测:外键不优化 2001 次查询 214 ms,select_related 1 次 10 ms;多对多用 prefetch_related 2 次;select_related 不能用于多对多;预取后再 filter 又会 N 次查询。

Django ORM select_related prefetch_related N+1 真实验证 动画演示
Django 2026-09-30

only()、defer() 触发的额外查询

实测 only() / defer():生成的 SQL 与被推迟字段;读了被推迟的字段会每行多一次查询(200 行 1 → 201 次);2000 行 × 10 KB 的 body 不同取法耗时 12.5 / 5.1 / 1.2 ms;带推迟字段的实例 save() 只更新已加载的列。

Django ORM only defer N+1 真实验证 动画演示
Django 2026-09-30

annotate()、aggregate() 与 SQL 聚合

实测 aggregate / annotate 与 SQL:没有关联行时 Count = 0、Sum = None;同时对两个多值关系聚合会被 JOIN 放大(ann 的书数 7 而不是 3);filter 放在 annotate 前后含义不同(WHERE / 再 JOIN / HAVING);Count(filter=Q) 生成 FILTER (WHERE);分组查询不套 Meta.ordering。

Django ORM 聚合 annotate aggregate 真实验证 动画演示
Django 2026-09-30

F() 表达式实现并发安全计数

在 PostgreSQL 上用 8 个线程各加 200 次计数:读-改-写最终 335(丢失 1265 次,5 轮都丢约 1260 次),update(n=F("n") + 1) 精确得到 1600;并对比两种写法的 SQL。

Django ORM F表达式 并发 PostgreSQL 真实验证 动画演示
Django 2026-09-30

Q() 对象与复杂查询条件

实测 Q 对象:& | ~ 对应的 SQL、动态拼条件与空 Q 的陷阱(空 Q 在 | 里被忽略);多值关系上 filter(a, b) 与 filter(a).filter(b) 的语义差别;exclude 用 NOT EXISTS 子查询,与 filter 取反不同。

Django ORM Q对象 查询 真实验证 动画演示
Django 2026-09-30

values()、values_list() 与对象查询性能

5 万行读入内存:模型对象 134 ms / 42 MiB,values() 29 ms / 17 MiB,values_list(flat=True) 18 ms / 5.1 MiB;only() 省内存但仍构造对象;values 系列拿不到模型上的方法。

Django ORM values 性能 真实验证 动画演示
Django 2026-09-30

exists()、count()、len() 的区别

20 万行上量 exists() / count() / len() / bool():exists 0.22 ms,count 2.48 ms,len 与 bool 各 615 ms 且占约 137 MiB;len(list(values_list)) 也要 59 ms;以及缓存对答案的影响。

Django ORM exists count 真实验证 动画演示
Django 2026-09-30

get_or_create() 的并发问题

在 PostgreSQL 上用 8 个线程并发 get_or_create:有唯一约束时每轮恰好 1 行、无异常;没有唯一约束时 20 轮全部出现重复行,之后 get_or_create 永久抛 MultipleObjectsReturned;update_or_create 同样依赖唯一约束。

Django ORM get_or_create 并发 PostgreSQL 真实验证 动画演示
Django 2026-09-30

bulk_create() 与 bulk_update() 的限制

实测 bulk_create / bulk_update:5000 条循环 save() 5000 次查询 1777 ms,bulk_create 1 次 66 ms;bulk 不触发信号;ignore_conflicts 不回填 pk;多表继承不支持;本机 SQLite 上 bulk_update 未必比逐个 save 快。

Django ORM bulk_create bulk_update 真实验证 动画演示
京ICP备2026067502号-1京公网安备11010502063487号