On this page · 13 sections
- The two announcements that changed Django planning this month
- Django 6.1: the ORM changes are the reason to care
- The upgrade has an infrastructure bill attached
- Django or Node: the honest version
- Python versions decide the real deadline
- Security cadence you have to staff for
- What we build
- Our delivery process
- Why eCorpIT
- India-specific considerations
- FAQ
- How eCorpIT can help
- References
Summary. Django 6.1 was released on 5 August 2026 and supports Python 3.12, 3.13 and 3.14. It raises the database floor hard: PostgreSQL 15 or higher, MySQL 8.4 or higher, MariaDB 10.11 or higher, SQLite 3.37.0 or higher. It also adds QuerySet.fetch_mode(), which the release notes say reduces most cases of the N+1 query problem to two queries. Separately, Django's Steering Council accepted DEP 20 on 10 August 2026: from January 2028 there is one release a year, every release carries three years of support, and the LTS label is retired. Django 4.2 LTS already left extended support on 7 April 2026, and Node 20 hit end of life on 30 April 2026. If a stack decision is on your table this quarter, both of those dates matter more than any framework benchmark.
The two announcements that changed Django planning this month
For a decade the awkward part of running Django in production has been the LTS gap. You either upgraded every eight months, or you sat on an LTS release and then jumped two years of changes at once when it expired. Most teams chose the second and paid for it.
That ends. Django's Steering Council accepted DEP 20 on 10 August 2026. From January 2028 Django makes one feature release a year, version numbers carry the year (Django 2028, Django 2029, Django 2030), and every feature release gets three years of support: one year of mainstream bugfixes, then two years of security and data-loss fixes. Writing on the Django Software Foundation weblog, Carlton Gibson set out the practical effect: "No more LTS gap: no racing a deadline to jump two years of changes at once. Upgrade one year at a time, whenever suits you within the support window."
The Python alignment is the other half. Under the new cycle each Django version supports the three latest Python versions at release and picks up the new Python during its first year, and Django's support window ends in step with its oldest supported Python. That removes the situation where an LTS carried a Python matrix stretching past Python's own end of life.
| Release | Date | End of mainstream support | End of extended support |
|---|---|---|---|
| Django 5.2 LTS | April 2025 | 3 December 2025 | April 2028 |
| Django 6.0 | December 2025 | 4 August 2026 | April 2027 |
| Django 6.1 | August 2026 | April 2027 | December 2027 |
| Django 6.2 LTS | April 2027 | December 2027 | April 2030 |
| Django 2028 | January 2028 | January 2029 | January 2031 |
Django 6.2 is the final release under the old versioning and support policy. Support commitments already made for 5.2 LTS and 6.2 LTS stand.
Django 6.1: the ORM changes are the reason to care
Django 6.1's release notes contain three changes that alter how a data-heavy application is written, not just how it is configured.
Model field fetch modes. QuerySet.fetch_mode() takes FETCH_ONE (the default), FETCH_PEERS, or FETCH_RAISE. The notes state that FETCH_PEERS reduces most cases of the N+1 query problem to two queries. FETCH_RAISE raises FieldFetchBlocked instead of silently issuing a query, which turns an entire class of production performance bug into a test failure. For an application where the data model is the product, this is the single most valuable thing in the release.
Database-level delete options. ForeignKey.on_delete now accepts DB_CASCADE, DB_SET_NULL and DB_SET_DEFAULT, implemented with the SQL ON DELETE clause rather than in Python. Read the caveat before using it: DB_CASCADE does not fire the pre_delete or post_delete signals. Any audit log or cache invalidation hanging off those signals will silently stop running.
Mailers. A new MAILERS setting supports multiple email backends, and the notes say it will replace EMAIL_BACKEND and the related EMAIL_* settings in Django 7.0, with deprecation warnings until then. Every EMAIL_* setting and mail.get_connection() began deprecation in 6.1, so a 2026 build should be written against MAILERS from the start.
Smaller but worth noting: the PBKDF2 default iteration count rose from 1,200,000 to 1,500,000, there is a new csp_nonce_attr template tag with a security.W027 check behind it, and UUID4, UUID7 and JSONNull arrived as database functions with BitAnd, BitOr and BitXor promoted out of contrib.postgres.
The upgrade has an infrastructure bill attached
This is the part quotes leave out. Django 6.1 drops PostgreSQL 14, drops MySQL below 8.4, drops MariaDB below 10.11, and raises the SQLite minimum from 3.31.0 to 3.37.0. On the GIS side, PostGIS 3.1, GEOS 3.8 and 3.9, and GDAL 3.1 and 3.2 support are all removed.
So "upgrade Django" can mean "upgrade the managed database instance", which is a maintenance window, a version-compatibility test pass, and sometimes a price change on the hosting bill. We size that in discovery rather than discovering it during the sprint.
Four more backwards-incompatible changes deserve a regression test:
Cache keys changed for pages and template fragments that vary on additional information, so the first request to any previously cached page is a cache miss after the upgrade. MultiPartParser and DatabaseCache now use strict Base64 validation, and existing cache entries with non-standard or corrupted Base64 may no longer be readable. SQL SELECT, table and JOIN aliases are now systematically quoted, which can break raw SQL that references mixed-case aliases through RawSQL. And first() and last() no longer order by primary key when order_by() was called with no arguments, which quietly changes results in code that relied on the old behaviour.
# Django 6.1: collapse an N+1 into two queries, and fail loudly on the ones you missed
qs = Order.objects.fetch_mode(FETCH_PEERS) # peers fetched in one extra query
strict = Order.objects.fetch_mode(FETCH_RAISE) # raises FieldFetchBlocked in tests
Django or Node: the honest version
Both are good. The decision should turn on where the complexity sits, not on which is faster in a synthetic benchmark.
| Decision factor | Django | Node.js |
|---|---|---|
| Support window | 3 years per release from Django 2028; 5.2 LTS runs to April 2028 | 30 months per LTS line: 12 months active, then 18 maintenance |
| Currently supported lines | 5.2 LTS, 6.0, 6.1 | 26.x Current, 24.x Active LTS, 22.x Maintenance |
| Nearest end of life | Django 6.0 extended support ends April 2027 | Node 22 ends 30 April 2027; Node 20 already ended 30 April 2026 |
| Data layer | ORM, migrations, admin and constraint handling in the framework | Chosen per project: Prisma, Drizzle, TypeORM or raw SQL |
| Where the effort goes | Modelling the domain correctly up front | Assembling and maintaining the data layer yourself |
| Best fit | Records, workflow, reporting, admin-heavy internal systems | High-concurrency I/O, realtime, one language across the stack |
The Node.js release schedule is precise about the window: every even major is actively maintained for 12 months from the date it enters LTS coverage, then transitions to maintenance for 18 months. Node 24 is the Active LTS line with end of life on 30 April 2028; Node 22 is in maintenance until 30 April 2027; Node 20 reached end of life on 30 April 2026.
The practical rule we use: if the hard part of the system is the data model, its constraints, its migrations and who is allowed to see what, Django gets you further before you have to build infrastructure. If the hard part is concurrent connections and a shared language between browser and server, Node does. Choosing Django because "Python is easier" and then hand-rolling an API layer that fights the ORM is how a Django project goes wrong.
Python versions decide the real deadline
Python's version status table puts Python 3.10 at security-only with end of life scheduled for October 2026, 3.11 security-only to October 2027, and 3.12 security-only to October 2028. Django 5.2 supports Python 3.10 through 3.14; Django 6.1 supports only 3.12, 3.13 and 3.14.
That gives a clean planning rule for 2026: target Python 3.13 or 3.14, because a build started on 3.10 today is on a runtime that leaves support within months. The same reasoning drives our legacy PHP work, and it is the reason we check runtime end-of-life dates before writing a line of a proposal.
Security cadence you have to staff for
Django ships security releases on a monthly rhythm. The 4 August 2026 releases shipped Django 6.0.8 and 5.2.17 and fixed four issues, including CVE-2026-15307, a high-severity server-side file-write and request forgery via spatial lookups, and CVE-2026-15920, cross-site scripting through URLField values in the admin. That release was backwards-incompatible: dict and non-GEOSGeometry str values are no longer allowed in spatial lookups.
The 3 February 2026 releases shipped 6.0.2, 5.2.11 and 4.2.28 against six CVEs, three of them high severity, including SQL injection via QuerySet.order_by() and FilteredRelation (CVE-2026-1312) and SQL injection in column aliases via control characters (CVE-2026-1287).
The point for a buyer is not the CVE numbers. It is that a Django application needs someone whose job is to apply patch releases within days, and that this is a running cost, not a project cost. Our software testing team maintains the regression suite that makes a same-week patch upgrade a safe, boring event.
What we build
Four shapes, and the price differs by shape rather than by line count.
A product backend: Django plus Django REST Framework or a typed API layer, PostgreSQL, Celery or a task queue for the asynchronous work, and a deployment pipeline. An internal operations system: heavy use of the Django admin where it fits, custom views where it does not, role-based permissions, and reporting. A data-heavy application: the case where the ORM, indexes, constraints and query plans are the engineering, and where 6.1's fetch modes now do real work. And a rescue or upgrade: an application stuck on Django 4.2 or earlier, which is already out of extended support, or on a Python version that is out of active support.
Where the application has to feed dashboards or a warehouse, that work usually crosses into our data engineering services practice, and where it exposes a public interface to partners, our API development team. If the deployment target is moving at the same time, our cloud migration services group runs that in the same programme.
Our delivery process
- Discovery, 1 week. Current Django and Python versions, database engine and version against the 6.1 floor, third-party package inventory with each package's own support status, and the actual query profile from production. The upgrade cost falls out of this, not out of a guess.
- Domain model, 1 week. Entities, constraints, indexes, and the migration plan. Composite primary keys, available since Django 5.2, are on the table where they belong. This is the week that decides whether year three is cheap or expensive.
- Build, 4-12 weeks. Application, API, background jobs, tests. Pinned Django and Python versions in the lockfile, and CI that fails on a deprecation warning rather than logging it.
- Hardening and launch, 1-3 weeks. Query plans reviewed under realistic data volume,
FETCH_RAISEused in tests to find the N+1s, security settings checked including the newsecurity.W027content-security-policy check, and a rehearsed rollback.
- Run. Patch releases applied on the monthly Django cadence, feature upgrades planned against the support table above, and a quarterly review of package and runtime end-of-life dates.
Why eCorpIT
eCorp Information Technologies Private Limited was founded in 2021 and works from Gurugram, Haryana. We are CMMI Level 5 appraised, MSME certified, and ISO 27001:2022 certified, and we are a partner of AWS, Microsoft and Google. Teams are senior-led and multi-disciplinary, which for a Django engagement means an engineer who reads query plans sits on the project from week one rather than being called in when it is slow.
We work to an engagement model, not a rate card. Discovery is a fixed-price package that produces the upgrade and infrastructure cost model. A build is fixed-scope once the domain model is signed, because the domain model is what makes an estimate meaningful. Long-running product work is a monthly dedicated squad; if you would rather own the roadmap and add engineers to your own team, our staff augmentation services page covers that arrangement.
India-specific considerations
Two points matter for Indian teams. First, hosting: Django 6.1's PostgreSQL 15 floor means checking the managed database version your provider actually offers in the Mumbai or Hyderabad region before committing to the upgrade, because regional version availability lags. Second, privacy: a Django application holding customer records is processing personal data under the Digital Personal Data Protection Act 2023, so retention and deletion belong in the model layer. Django's new database-level DB_CASCADE makes deletion cheaper to implement, with the caveat above that it bypasses pre_delete and post_delete signals, which is exactly where a naive audit-log implementation would sit. We design Django applications aligned with DPDP requirements, with retention encoded in the schema and a deletion path that is tested rather than assumed.
FAQ
How eCorpIT can help
We scope Django work from the version table outward: what Django and Python versions you run, what database engine and version sits underneath, which third-party packages have their own end-of-life dates, and what the production query profile actually looks like. That inventory decides whether you need an upgrade, a rebuild, or a domain model rewritten before either. If you are choosing between Django and Node for a new system, or you are on Django 4.2 and out of support, send us the stack and we will come back with a scoped plan and an engagement model. Start at /contact-us/.
References
Last updated: 18 August 2026.