实测 dumpdata / loaddata:输出格式与 natural key;loaddata 不调用自定义 save()、auto_now 保留文件里的值、post_save 以 raw=True 触发;同 pk 是覆盖;坏字段与坏外键的报错;1 万行 dumpdata 0.19 s、loaddata 1.41 s。
用带日志的字段与表单实测 Form 完整校验流程:构造时不校验;is_valid() 触发;每个字段 to_python → validate → run_validators → clean_<field>;再表单级 clean() 与 _post_clean();字段失败时 clean_<field> 被跳过、cleaned_data 缺该键;disabled 与多余字段的处理。
实测 Django 校验器:模型字段的 validators 在 save() 时不运行、full_clean() 才运行;所有 validators 错误累加;ModelForm 在 _post_clean 里运行模型校验;unique 由 full_clean 查库、save() 由数据库约束兜底;可配置校验器需要 @deconstructible。
实测 Form 与 ModelForm 的区别:字段自动生成、fields = "__all__" 让用户改到 is_featured(白名单则被忽略)、校验包含 unique 与模型 validators、校验失败后 instance 在内存里已被改写。
实测 ModelForm.save(commit=False):不发任何查询、返回 pk=None 的对象;多对多要等 save_m2m();忘了 save_m2m() 时多对多悄悄丢失且不报错;标准写法是补上服务端字段后 save() 再 save_m2m()。
实测 ModelForm 多对多保存:save_m2m 用 set() 做差集(标签 {a,b} → {b,c} 只 DELETE a、INSERT c);取消全部勾选会清空;queryset 是校验白名单;自定义 through 模型的额外字段只能取默认值。
实测 FormSet 与 InlineFormSet:ManagementForm 的字段与缺失时的错误(missing_management_form);min_num / max_num / validate_min / validate_max / can_delete;inline 自动关联父对象;10 个表单的外键下拉框渲染发出 11 次查询(N+1)。
在 gunicorn 上实测文件上传:默认 FILE_UPLOAD_MAX_MEMORY_SIZE=2.5 MiB,≤ 阈值是 InMemoryUploadedFile、超过是磁盘上的 TemporaryUploadedFile;200 MiB 上传 worker 峰值 46 MiB(落盘)vs 246 MiB(阈值调大后留在内存);FILE_UPLOAD_TEMP_DIR 指定临时目录。
实测 Django 的上传大小限制:没有单文件上限(30 MiB 也接受);表单里检查 file.size 发生在文件收完之后;DATA_UPLOAD_MAX_MEMORY_SIZE 不计文件字段(10 MiB 文件通过、3 MiB 普通字段被拒);DATA_UPLOAD_MAX_NUMBER_FILES 默认 100,101 个抛 TooManyFilesSent。
实测 CSRF:cookie 里是 32 位 secret(不变),表单 token 是 64 位且每次不同(掩码);缺 token / 错 token / 缺 cookie 都是 403,请求头 X-CSRFToken 可用;通过 login() 登录会轮换 cookie 并使旧表单 token 失效,logout 不轮换。
实测 Django 用户认证流程:request.user 是惰性的(不访问则 0 次查询,访问一次 2 次:session + user);authenticate 依次尝试后端、失败发 user_login_failed(信号里的凭据只保留键名);登录后 session 只存用户 id、后端路径和密码派生的 hash。
实测 Session 默认(数据库后端)如何保存登录状态:只读不创建 session、写入才发 Set-Cookie;session 表的 key / data / expire_date;每个请求 1 次 SELECT、修改再 UPDATE;默认固定 14 天过期;过期行不会自动清理,需要 clearsessions。