Safeguard
Developer Tools•

How do Django deprecations work, and how do you plan LTS upgrades?

Django keeps deprecated features working for at least two feature releases and warns first. See what that means for planning an LTS to LTS upgrade.

Safeguard Security Team
4 min read

Django deprecates a feature over at least two feature releases: it keeps working and raises a warning, then it is removed. LTS releases get security fixes for about three years. To move between LTS versions safely, fix every warning on the old LTS, then step to the next.

The policy in plain words

The Django release process page lays out a predictable cycle. A feature deprecated in release A.x keeps working in every A.x version but raises warnings. It is removed in a later release, with a minimum of two feature releases between deprecation and removal. The page gives a worked example: a function deprecated in 4.2 raises a RemovedInDjango51Warning in 4.2, still exists in 5.0, and is gone in 5.1.

Version numbers follow a loose form of semantic versioning. Each release after an LTS bumps to the next dot zero, so you see 4.2 (LTS), 5.0, 5.1, 5.2 (LTS). Long-term support releases get security and data loss fixes for a guaranteed period, typically three years, according to the same page.

There is one detail that surprises people. Deprecations started in an LTS release are dropped in a non-dot-zero release, to honor the rule of keeping shims for at least two feature releases. The page says third party apps need to maintain compatibility back to the earlier LTS to ease LTS to LTS upgrades.

What this means for your plan

If you run an LTS and want the next LTS, you have two routes.

RouteHow it worksTrade-off
Jump LTS to LTSFix all warnings on the current LTS, then move straight to the next LTSFewer upgrade events, but a larger change set
Step through every feature releaseUpgrade one release at a timeSmaller steps, more frequent work, shorter support on each stop

The deprecation policy is what makes the jump possible. If your code runs on the old LTS with no deprecation warnings, the shims you depended on are not needed by the next LTS.

Steps for an LTS to LTS upgrade

  1. Confirm the current support status of your version and your target on the official download page, since dates shift.
  2. On the current LTS, run your tests with warnings visible. Django says the warnings are silent by default and can be shown with Python's development warning option.
python -Wd manage.py test
  1. Fix warnings in your own code first. Then upgrade third party packages to releases that declare support for the target version.
  2. Upgrade packages that your project depends on before the framework, where they are compatible with both versions.
  3. Move to the target LTS on a branch, run migrations on a copy of production data, and run the full suite.
  4. Release behind your normal staging soak.

Security reasons not to wait

Support windows end. An unsupported release stops receiving security fixes from the project. If you are past the window, an upgrade is no longer a convenience. Plan it as a risk item with an owner and a date, and record the exception if you must run unsupported for a while.

Quick check

Do deprecation warnings appear by default in Django?

No. They are silent by default and appear when you enable Python warnings in your test run.

Can I skip from one LTS directly to the next?

The policy is designed to allow it, as long as your code is clean of deprecation warnings on the older LTS and your packages support the target.

Safeguard maps your dependency inventory and flags end of support components, and a free scan is available at gold.safeguard.sh/scan.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.