django/django
Architecture
Django is organised around the request/response cycle. A request enters through a server gateway (WSGI or ASGI), gets dispatched through middleware, routed to a view, and the view returns a response that travels back through the same middleware stack. Most of the framework's other subsystems — the ORM, templates, forms, sessions, auth, the admin — exist to make views easy to write.
High-level component map
graph TD
Server[WSGI/ASGI server<br/>gunicorn, uvicorn, daphne]
Handler["django.core.handlers<br/>WSGIHandler / ASGIHandler"]
MW[Middleware chain]
Resolver["django.urls<br/>URLResolver"]
View["django.views<br/>View / function view"]
ORM["django.db.models<br/>QuerySet, Manager"]
DB[(Database backend)]
Tpl["django.template<br/>Engine, Loader"]
Forms["django.forms"]
Resp["django.http<br/>HttpResponse"]
Server -->|environ / scope| Handler
Handler --> MW
MW --> Resolver
Resolver --> View
View --> ORM
ORM --> DB
View --> Tpl
View --> Forms
View --> Resp
Resp --> MW
MW --> Handler
Handler -->|response| ServerEach box maps to a specific package in the source tree. The handler glue lives in django/core/handlers/ (base.py, wsgi.py, asgi.py, exception.py). Middleware classes live in django/middleware/ and django/contrib/*/middleware.py. Routing lives in django/urls/ (resolvers.py is the workhorse). The view layer is split between functional views and class-based views in django/views/generic/.
Request lifecycle
sequenceDiagram
participant Client
participant Server as WSGI/ASGI server
participant Handler as BaseHandler
participant MW as Middleware
participant Resolver as URLResolver
participant View
participant DB
Client->>Server: HTTP request
Server->>Handler: environ / scope
Handler->>Handler: HttpRequest construction
Handler->>MW: process_request (each MW)
MW->>Resolver: resolve(path)
Resolver-->>MW: ResolverMatch (view, args, kwargs)
MW->>View: view(request, *args, **kwargs)
View->>DB: ORM queries (optional)
DB-->>View: rows
View-->>MW: HttpResponse
MW->>Handler: process_response (reverse order)
Handler-->>Server: status, headers, body
Server-->>Client: HTTP responseBaseHandler.get_response() in django/core/handlers/base.py is the orchestrator. It compiles the middleware chain once at startup (load_middleware()), constructs the inner _get_response callable, and dispatches the request. The async path in ASGIHandler (django/core/handlers/asgi.py) mirrors the sync path with async def versions and the asgiref.sync adapters wrapping any sync-only middleware.
Subsystem topology
graph LR
subgraph "django.conf"
Settings[settings lazy object]
end
subgraph "django.apps"
AppRegistry[AppRegistry]
end
subgraph "Request layer"
HTTP[django.http]
URLs[django.urls]
Views[django.views]
MWares[django.middleware]
end
subgraph "Data layer"
ORM[django.db.models]
Backends[django.db.backends]
Migrations[django.db.migrations]
end
subgraph "Presentation"
Templates[django.template]
Forms[django.forms]
end
subgraph "django.core"
Handlers[handlers]
Mgmt[management]
Cache[cache]
Mail[mail]
Signing[signing]
Validators[validators]
end
subgraph "django.contrib"
Admin[admin]
Auth[auth]
ContentTypes[contenttypes]
Sessions[sessions]
Messages[messages]
Sites[sites]
StaticFiles[staticfiles]
GIS[gis]
Postgres[postgres]
end
Settings --> AppRegistry
AppRegistry --> ORM
AppRegistry --> Admin
Handlers --> MWares
MWares --> URLs
URLs --> Views
Views --> Templates
Views --> Forms
Views --> ORM
ORM --> Backends
ORM --> Migrations
Forms --> ORM
Admin --> ORM
Admin --> Forms
Admin --> Templates
Auth --> ORM
Auth --> SessionsKey cross-cutting systems
The apps registry — django/apps/registry.py exposes a singleton AppRegistry that tracks every installed app, its models, and the order they were loaded. django.setup() (in django/__init__.py) populates it. Almost every other subsystem reaches into the registry: the ORM uses it to resolve string references like "auth.User", the admin uses it to autodiscover admin.py modules, migrations use it to find models per app label.
Settings — django/conf/__init__.py defines a lazy settings object that imports the user's settings module on first access. global_settings.py provides the defaults. Almost every subsystem reads from settings, so changing a setting at runtime usually does the wrong thing.
Signals — django/dispatch/dispatcher.py provides a synchronous publish/subscribe primitive. Built-in signals include pre_save/post_save, pre_delete/post_delete, request_started/request_finished, setting_changed, and the auth signals. Signals are used internally to decouple the ORM from contrib apps that need to react to changes (e.g., django.contrib.contenttypes listens to post_migrate).
System checks — django/core/checks/ is a registration framework that runs a set of validation functions at startup and as part of manage.py check. Each subsystem that needs validation registers tags (models, admin, urls, templates, security, etc.). Checks run in the same process and produce Warning/Error messages with stable IDs.
Async/sync boundary — Django supports both sync and async views and middleware. The dual support is implemented with asgiref.sync.async_to_sync and sync_to_async wrappers. django/utils/asyncio.py adds the async_unsafe decorator for code paths that must run outside an async event loop. Most middleware can be marked sync_capable and async_capable simultaneously and the handler chooses the cheaper path.
How data moves through the ORM
graph LR
Code["model.objects.filter(...)"]
QS["QuerySet<br/>django/db/models/query.py"]
Q["Q / F objects<br/>query_utils.py, expressions.py"]
SQL["sql.Query<br/>django/db/models/sql/query.py"]
Compiler["SQLCompiler<br/>sql/compiler.py"]
Backend["DatabaseWrapper<br/>django/db/backends/<engine>/base.py"]
DBMS[(SQLite / PostgreSQL /<br/>MySQL / Oracle)]
Code --> QS
QS --> Q
QS --> SQL
SQL --> Compiler
Compiler -->|SQL string + params| Backend
Backend --> DBMS
DBMS -->|rows| Backend
Backend -->|tuples| Compiler
Compiler -->|model instances| QS
QS -->|iterable| CodeQuerySet is the user-facing builder. Internally it owns a sql.Query object that tracks joins, filters, annotations, and ordering. When the queryset is evaluated, Query.get_compiler(using).as_sql() produces a (sql, params) tuple that the backend wrapper executes. The backend wrappers in django/db/backends/{sqlite3,postgresql,mysql,oracle}/ translate generic SQL fragments into engine-specific syntax via DatabaseOperations, DatabaseFeatures, and DatabaseSchemaEditor classes.
For deeper coverage of each subsystem, see the pages under systems/.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.