How to upgrade Django to a newer version

虽然有时是个复杂的过程,将 Django 升级到最新版有以下好处:

  • 新功能和优化
  • 已修复的 bug。
  • 旧版 Django 最终将不再收到安全更新。(参考 支持的版本
  • 随着每个新 Django 发行版的发布而升级,可以使您的代码库保持最新,从而减少将来升级带来的痛苦。

有些事情需要你考虑,这有助于使升级流程尽可能顺滑。

必读内容

若这是你第一次进行升级操作,那么阅读 不同发行进程的指南 就非常有用。

Afterward, you should familiarize yourself with the changes that were made in the new Django version(s):

  • 阅读当前版本之后的每个“最终”版本的 发行说明 ,包括计划升级的版本。
  • 阅读 过期时间表 获取相关版本信息。

特别注意向前兼容修改,清楚了解成功的升级需要做什么。

若你更新的版本跨度超过一个特性版本(例如从 2.0 更新到 2.2),通常增量更新(从 2.0 到 2.1 再到 2.2)每个版本会比一次性更新更容易。对于每个发布特性,使用最新的补丁版本(例如,对于 2.1,使用 2.1.15)。

从一个长期支持(LTS)版本更新至下一个长期更新版本时,特别推荐同样的增量更新方法。

依赖

大多数情况下,将 Django 的依赖升至最新版本是必要的。若 Django 版本是最近发布的,但某些依赖没有很好适配,这些依赖可能无法支持最新版的 Django。这种情况下,你只能等新版本的依赖发布。

处理过期警告

在升级前,将使用当前 Django 版本引发的过期警告解决掉是个不错的注意。在升级前修复这些警告能确保你了解代码中哪些部分需要修改。

在 Python 中,过期警告默认是静默的。你必须用 Python 的命令行选项 -WaPYTHONWARNINGS 环境变量将其打开。例如,在运行测试时显示警告:

Linux/MacOS     Windows

  1. $ python -Wa manage.py test
  1. ...\> py -Wa manage.py test

If you’re not using the Django test runner, you may need to also ensure that any console output is not captured which would hide deprecation warnings. For example, if you use pytest:

  1. $ PYTHONWARNINGS=always pytest tests --capture=no

在继续升级流程前处理当前 Django 版本报告的所有过期警告。

第三方应用可能会出于兼容多版本 Django 目的使用过期 APIs,所以你安装的应用报告的过期警告可能并不是问题。若某个包不支持最新版的 Django,考虑为其创建一个 issue 或发起一个 pull request。

安装

准备好后,就是 :doc:`安装新版 Django ` 的时候。若你正使用 :mod:`virtual environment `,且这是一次关键性升级,你可能想要先配置一个包含所有依赖的环境。

若你用 pip 安装 Django,你可以使用 --upgrade-U 标志:

Linux/MacOS     Windows

  1. $ python -m pip install -U Django
  1. ...\> py -m pip install -U Django

测试

当环境准备好后,先为应用 运行完整的测试套件。再说一次,将过期警告开关打开很有用,这样就能在测试输出中看到过期警告(若你用 manage.py runserver 手动测试,也能有该标志):

Linux/MacOS     Windows

  1. $ python -Wa manage.py test
  1. ...\> py -Wa manage.py test

在你运行测试,并修复所有问题后。由于你刚看了发布说明,可能现在也是重构代码,消除所有过期警告,尝尝 Django 最新功能特性的好时机。

部署

当你十分确信你的应用能兼容新版 Django 时,你就准备好去往下一步, 部署 升级后的 Django 工程。

若你使用 Django 提供的缓存,你需要考虑在升级后清空缓存。否则,你可能会卷入麻烦中,举个例子,若你缓存了 pickled 对象,而这些对象并不能确保跨版本 pickle 兼容。一个过期兼容性例子是缓存 pickled HttpResponse 对象,不论是直接或间接由 cache_page() 装饰器创建。