知其然,知其所以然
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 真实验证 动画演示
Django 2026-09-30

Model Manager 与自定义 QuerySet

实测自定义 QuerySet + as_manager() 的链式调用、覆盖默认 Manager 做软删除;关系访问(book.author)与 JOIN 不走自定义 Manager,已软删除的对象仍能被取到;默认 Manager 是模型里第一个定义的。

Django ORM Manager QuerySet 软删除 真实验证 动画演示
Django 2026-09-30

自定义模型字段

写一个 list ↔ 逗号文本的自定义字段,记录 to_python / from_db_value / get_prep_value / value_to_string 在构造、保存、查询、values_list、full_clean、序列化时各自被调用的时刻;并验证 deconstruct 漏写参数会让 makemigrations 检测不到变化。

Django ORM 自定义字段 Field 真实验证 动画演示
Django 2026-09-30

自定义 Lookup 与 Transform

实测自定义 Lookup(__ne)与 Transform(__abs):生成的 SQL、叠加使用、在 values_list / order_by 里的使用;注册在 Field 基类上会让所有字段都有它;PostgreSQL EXPLAIN 显示 Lower(name) 函数索引对 annotate(Lower) 有效,对 __iexact(UPPER)无效。

Django ORM Lookup Transform PostgreSQL 真实验证 动画演示
Django 2026-09-30

Django ORM 如何生成 SQL

拆开 Django ORM 生成 SQL 的过程:QuerySet 包着的 Query 是条件树而不是字符串;compiler 按数据库后端编译出不同方言(SQLite LIKE vs PostgreSQL UPPER(...) LIKE UPPER(...));构建 65 µs、编译 84 µs、整体 262 µs;看 SQL 的几种办法。

Django ORM SQL 编译 真实验证 动画演示
Django 2026-09-30

使用 QuerySet.explain() 分析执行计划

用 QuerySet.explain() 在 PostgreSQL 与 SQLite 上看执行计划:无索引 Seq Scan、加索引后 Bitmap Index Scan(估算成本 3774 → 536)、选择性差时仍全表扫描;analyze=True 给出实际耗时(0.175 ms),buffers / format 选项;explain 只能用在 QuerySet 上。

Django ORM explain 执行计划 PostgreSQL 真实验证 动画演示
Django 2026-09-30

数据库连接生命周期

在 gunicorn + PostgreSQL 上观察 Django 的数据库连接生命周期:连接是惰性的;默认每个请求一个新的数据库后端进程(6 个请求 6 个 pid);请求结束连接被关闭;连接是线程局部的(4 个线程 = 4 个连接);CONN_MAX_AGE=None 时连接在请求结束后仍保持。

Django 数据库连接 PostgreSQL gunicorn 真实验证 动画演示
京ICP备2026067502号-1京公网安备11010502063487号