That said, jumping a bunch of releases (e.g. 1.11 -> 3.0) actually often works out just fine, especially if I've got good test coverage. It's just that when it doesn't work, it can be tricky to find out what's going wrong. That's because the release notes are typically written with just a single step in mind, so with a bunch of releases I find myself scrambling to figure out which set of notes I need to read.
The best thing to go is run the dev server with `python -Wd` to get the depreciation warnings, and fix them before each upgrade. Worked perfectly!
Of course it depends on your codebase. In the past I worked on a project which interacted a lot with Django internals, with a lot of code reflection involved. Upgrading that was a pain even between minor releases.
It's not much work, and you might just take the opportunity to stop and read the release notes of each release and find something useful there.