django/django
Lore
A timeline of how Django got from a Kansas newsroom in 2003 to a 165-kLOC framework with 34,500 commits and a 1,150-name AUTHORS file. Dates are derived from git history, release tags, and notes in docs/releases/.
Eras
The Lawrence Years (Jul 2003 – Jul 2005)
Django was built at the Lawrence Journal-World newspaper by Adrian Holovaty and Simon Willison to support fast-turnaround news applications. The earliest commits in the public repository are dated 2005-07-13 ("Created basic repository structure", "Imported Django from private SVN repository (created from r. 8825)") — the framework already existed in a private SVN repo before that. The newspaper era set the template for many design choices that survive today: the admin (built so journalists could enter data), the URL dispatcher (newsroom apps had complex URL hierarchies), the ORM (the team didn't trust raw SQL across many small apps), and reusable apps (django/contrib/).
Public release and magic-removal (Jul 2005 – Sep 2008)
Django was open-sourced in July 2005. The first public years were dominated by the "magic removal" branch — a refactor that replaced auto-magical class behavior with explicit Python idioms. Django 1.0 shipped on 2008-09-03 with a public-API stability promise. Commit volume was high: 2005–2008 alone account for over 6,000 commits.
The 1.x era (Sep 2008 – Dec 2017)
The 1.x line ran for nearly a decade and 11 minor releases. The key milestones:
- 1.0 (Sep 2008) — API stability, the original
django.contrib.gis. - 1.1 (Jul 2009) — aggregations, transactional tests.
- 1.4 (Mar 2012) — first LTS release; timezone-aware datetimes.
- 1.5 (Feb 2013) — Python 3 support; pluggable user model.
- 1.7 (Sep 2014) — built-in migrations (replacing South); the
appsregistry; system checks. - 1.8 LTS (Apr 2015) — multiple template engines (Django + Jinja2 backends).
- 1.10 (Aug 2016) — middleware factory style (
__init__(get_response)). - 1.11 LTS (Apr 2017) — final 1.x release.
The 1.7 release is arguably the most consequential in Django's history: it absorbed the South migrations library into core, introduced the modern apps registry, and added the system checks framework. Most of the architecture documented in this wiki crystallised between 1.7 and 1.11.
The 2.x era (Dec 2017 – Apr 2019)
Django 2.0 (Dec 2017) dropped Python 2 support and introduced the path() URL syntax (in addition to the legacy url() regex syntax). 2.1 added permissions on the model admin; 2.2 LTS (Apr 2019) added constraints (UniqueConstraint, CheckConstraint).
The 3.x era and async (Dec 2019 – Apr 2021)
Django 3.0 (Dec 2019) added ASGI support — the framework now ran on async servers and could expose async views. The implementation is the bidirectional asgiref.sync bridge that lives in django/utils/asyncio.py and the dual sync/async middleware protocol in django/core/handlers/base.py. 3.1 added async views and the JSONField for all backends. 3.2 LTS (Apr 2021) added the default_auto_field setting and pathlib.Path support across the board.
The 4.x era (Dec 2021 – Apr 2024)
4.0 raised the minimum Python to 3.8 and refreshed the password hashers. 4.1 added async ORM (aget, acount, async iterators on QuerySet). 4.2 LTS (Apr 2023) added composite indexes, a pluggable database backend protocol, and BaseDatabaseWrapper.async_to_sync. The 4.2 LTS branch (stable/4.2.x) is still receiving security and data-loss fixes — see the 4.2.30 tag.
The 5.x era (Dec 2023 – Apr 2025)
5.0 generated more model field tooling (GeneratedField, db_default). 5.1 reworked the migrations questioner UI. 5.2 LTS (Apr 2025) added composite primary keys and made async ORM cover most of the QuerySet API.
The 6.x era (Dec 2025 – present)
6.0 (Dec 2025) is the active release line. Recent commits in main show ongoing work on:
- Composite primary key polish ("Fixed #36919 — Allowed Task and TaskResult to be pickled.")
- Template language deprecations (
#35738 — Deprecated double-dot variable lookups) - Admin form refinements (
#15759 — Fixed ModelAdmin.list_editable form submission) - Security clarifications (
CVE-2026-25674 — Clarified role of umask in upload permissions)
The version field in django/__init__.py reads VERSION = (6, 1, 0, "alpha", 0), so the next feature release is 6.1.
Longest-standing features
These subsystems have been continuously present and continuously evolving since the public release:
- The admin (
django/contrib/admin/) — present from day one. The newsroom origin made it the most polished part of Django for many years. - The ORM (
django/db/models/) — also present from day one. Most of the public API has been stable for 15+ years; the internals (thesql.Queryobject, the schema editor) have been rewritten multiple times. - The template language (
django/template/) — present from day one. Got pluggable backends in 1.8 (Apr 2015) but the original DTL syntax is unchanged. django/contrib/auth/— present from day one. Pluggable user model arrived in 1.5 (Feb 2013), password hashing was modernised in 4.0 and again in 5.0.django/contrib/gis/— present in 1.0 (Sep 2008). Originally a third-party app (GeoDjango) that was pulled into core.
Major rewrites
- Migrations (Sep 2014, 1.7) — the South library, written by Andrew Godwin, was rewritten and merged into core as
django/db/migrations/. The new system added a proper migration graph (graph.py), state replay (state.py), and an autodetector (autodetector.py). - The apps registry (Sep 2014, 1.7) — replaced ad-hoc model loading with the explicit
AppRegistry/AppConfigmodel. MadeINSTALLED_APPSstrings unambiguous and enabled the system checks framework. - Template engine pluggability (Apr 2015, 1.8) — the
TEMPLATESsetting andtemplate/backends/were introduced so that Jinja2 (and any other engine) could coexist with the Django Template Language. - Class-based views (Sep 2010, 1.3) — added
django/views/generic/as a class-based parallel to the original function-based generic views; the function-based versions were eventually removed. - Middleware factory style (Aug 2016, 1.10) — replaced the four-method middleware protocol (
process_request,process_view,process_response,process_exception) with a callable factory protocol, leavingMiddlewareMixinas a back-compat shim. - ASGI / async handler (Dec 2019, 3.0) — added
django/core/handlers/asgi.pyand theasync_to_sync/sync_to_asyncglue, parallelising the entire request path.
Deprecated features
- The original generic views — function-based views in
django.views.generic.*_viewwere replaced by class-based views in 1.3 and removed in 1.5. django.utils.six— Python 2/3 compatibility shims, removed when Python 2 support was dropped in 2.0.url()for regex patterns — soft-deprecated in favor ofpath()andre_path(); still present indjango/urls/conf.py.{% ifequal %}/{% ifnotequal %}— removed; the{% if %}tag handles equality.- South migrations — replaced by built-in migrations in 1.7.
django.contrib.formtools— extracted from core in 1.8.django.contrib.markup— removed in 1.6.django.contrib.databrowse— removed in 1.6.- Double-dot variable lookups in templates (e.g.,
{{ obj..attr }}) — deprecated in commit5d911f2d2f("#35738 -- Deprecated double-dot variable lookups").
Growth trajectory
Django reached its current shape early. By the end of 2010 (~6,300 commits in), the directory layout under django/ was already what you see today: db/, core/, forms/, template/, http/, urls/, views/, contrib/. Subsequent years added breadth (more contrib apps, more backends, async support, system checks, migrations) but the top-level shape didn't change.
The contributor base also reached a sustainable equilibrium: roughly 90 unique committers in any 90-day window, with a steady stream of new contributors funnelled through the Trac → patch → review → merge workflow. Django Software Foundation fellows (currently Mariusz Felisiak and Sarah Boyce) handle the bulk of triage and merge duties.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.