Skip to content
All writing
Backend21 Mar 2026·11 min read

Upgrading Django 2.2 to 5.2 Without a Feature Freeze

A staged approach to a multi-version framework upgrade across a live lending platform — and why the dependency graph is harder than the framework itself.

  • Django
  • Python
  • Modernization
  • Migrations

Long-lived platforms accumulate version debt quietly. Nothing breaks, so nothing gets prioritised — until a security advisory lands against a release that stopped receiving patches two years ago.

One version at a time, always deployable

The temptation is to branch, upgrade everything, and merge months later. That branch will never merge cleanly. The alternative is to move one minor version at a time, deploying at every step, so the system is never more than one hop from production-ready.

It feels slower. It is dramatically faster, because each step has a small, attributable blast radius. When something breaks after a single-version bump, you know exactly what changed.

The dependency graph is the real work

Django itself has excellent release notes and a well-signposted deprecation path. The third-party packages built on top of it do not. Some are abandoned, some renamed, some replaced by a standard-library feature three versions ago.

Auditing every dependency first — is it maintained, does it support the target version, is it still needed at all — turns up a surprising amount of code that can simply be deleted.

  • Bump one minor version per step and deploy each time
  • Audit dependencies before starting, not when they break
  • Treat every deprecation warning as an error in CI
  • Delete unused packages instead of porting them

Python and Django together

Moving Python 3.6 to 3.12 alongside the framework compounds the risk if done simultaneously. Sequencing them — clearing the Python runtime first where possible, then the framework — keeps each failure attributable to one variable.

Thoughts on this?

Always happy to talk through the engineering trade-offs.

Get In Touch

Related writing