2025-12-16,我提过一个要求:列一份从 Django 4.2 写法迁移到 5.2 的“完全等价 CE 基线写法清单”,要能直接冻结。当时的对话标题写的是“Django 5.0 与 4.2 对比”,正文讨论的却是 5.2,这个版本号上的出入我保留下来。
需要先说明:那是一次需求记录,不代表升级已经执行,也不代表所有行为已经验证等价。本文讲的不是“改哪些行就完事”,而是先定义什么叫等价,再列出需要验证的差异。
CE 基线不是版本号对齐
这里的 CE 基线,指这次要冻结的核心功能等价范围:同一组请求、同一组权限、同一份数据下,升级前后返回结构、状态变化和副作用一致。它不是把 Django==4.2.x 改成 Django==5.2.x,也不是把依赖装上去能启动就算完成。
一条基线至少要写清六件事:
| 字段 | 要写什么 | 反例 |
|---|---|---|
| 行为 | 用户或调用方能观察到什么 | “框架升级”太笼统 |
| 数据快照 | 用哪份固定数据、哪个提交号、哪套迁移 | 每次都在变化的开发库 |
| 4.2 写法 | 当前代码和配置 | 只写“默认配置” |
| 5.2 写法 | 需要改的代码或保持不动的理由 | 抄一段网上片段 |
| 验证方式 | 用哪条请求、哪张表、哪条断言确认 | “应该没问题” |
| 证据边界 | 没测到什么、依赖什么环境 | 只写“已测试”,不写环境和未覆盖项 |
表格按行为分行,不按包名分行。一个行为可能同时涉及依赖、配置和数据库,拆开记录更容易定位。
“数据快照”这一行最容易被省略。没有固定数据,升级前后跑的是两份不同的输入,结果差异就无法归因到框架。至少固定三件事:数据库备份或种子文件、代码提交号、迁移版本。如果做不到固定整库,就把关键表导出成可重复导入的样本,并在记录里写明样本覆盖了哪些状态。
五个需要单独登记的差异
1. Python 版本
根据 Django 5.2 发布说明,5.2 支持 Python 3.10 至 3.14;其中 3.14 自 Django 5.2.8 起受支持。应同时核对具体补丁版本。
先在 CI 和本地记录 python --version 与解释器路径,再决定升级顺序。如果生产环境仍停在 3.9,先查当前 Django 和目标 Python 的兼容范围,选择可测试的中间组合或在独立环境同时升级;能否分步部署取决于实际版本兼容性。
2. MySQL 连接字符集
发布说明指出,MySQL 默认连接字符集改为 utf8mb4;旧库需要兼容时可以在配置中显式指定旧字符集。
测试能否发现差异取决于数据库、连接配置和用例覆盖;应准备与目标环境相符的数据库集成测试。基线里要登记:连接的是哪个库、库和表的字符集、有没有依赖三字节 utf8 的旧数据。如果暂时不能改,显式写回旧字符集是过渡手段,但要记录原因和退出条件。以下仅展示相关配置片段,数据库名、连接凭据等仍需按环境补全:
DATABASES = {
"default": {
"ENGINE": "django.db.backends.mysql",
"OPTIONS": {
"charset": "utf8mb3"},
# 仅用于兼容旧库;记录迁移计划和移除条件
}
}
3. EmailMultiAlternatives 的 alternatives
发布说明要求通过 attach_alternative() 添加邮件的替代内容。
如果旧代码直接改 alternatives 列表,升级后可能不生效。基线里用一封同时包含纯文本和 HTML 的邮件验证:
from django.core.mail import EmailMultiAlternatives
msg = EmailMultiAlternatives("主题", "纯文本正文", "from@example.com", ["to@example.com"])
msg.attach_alternative("<p>HTML 正文</p>", "text/html")
msg.send()
以上片段是示意,没有在本轮发送邮件。验证时除检查是否发出,还要检查纯文本和 HTML 内容;如果项目涉及附件与编码,也应单独准备测试。
4. debug context processor
发布说明指出,新项目模板不再默认包含 debug() context processor。
注意它说的是默认项目模板,不是所有现有项目会被自动删掉。基线里要检查模板是否使用 debug 变量、settings 是否仍显式包含该 processor。新建项目与存量项目的结论可能不同,不能拿一条模板变更去推断全部项目。
5. 4.2 的支持期限
Django 发布说明载明 4.2 的支持期限至 2026 年 4 月。截至 2026 年 11 月,这一期限已过去;仍在使用的项目应尽快结合实际风险、兼容性与回滚能力制定迁移计划。基线表应记录当前版本、目标版本、计划日期和回滚窗口。
容易漏掉的三类验证
第一类是迁移。不要只看 migrate 是否成功,还要看生成的 SQL、默认值、索引名和回滚路径。测试库和生产库的版本差异也要记录。
第二类是权限和后台。框架升级后,管理后台的字段展示、过滤器、只读行为可能变化;这些不是单元测试的强项,需要按真实角色走查。
第三类是异步任务和定时任务。它们不在请求链路里,升级后最容易晚几天才暴露。基线表要列出任务名、触发方式、失败重试和告警接收人。
升级顺序
- 冻结当前行为:把关键接口、权限、导出和邮件写进基线表,保存当前版本的依赖快照、数据库备份和代码提交号。
- 阅读 5.0、5.1、5.2 三份 release notes,标出与项目相关的条目,不只看最终版本。
- 在独立环境升级 Python 和依赖,先跑静态检查和迁移检查,再跑集成测试。
- 用基线表逐项验证,未验证的项写“未测”,不要用“应该兼容”占位。
- 准备回滚:数据库备份、旧版本镜像、依赖快照和回滚演练缺一不可。
等价基线的作用不是让升级看起来没有风险,而是把风险写成可以逐项检查的条目。版本号对齐只是开始,行为对齐才是完成。
本文由 AI 助手依据本人历史素材起草;2025-12-16 的基线清单是当时需求,本轮未执行升级或迁移;Django 官方文档引用已在文中标注,未覆盖 5.0、5.1 的全部变更。