# Data flow — django/django

> Canonical page: https://codevetter.com/unpack/django/data-flow

# Data flow — django/django

Scanned commit dd6f6b1531984823e3dc56740dfa93f3ceb09357 (2026-09-20). Generated by codevetter codevetter 1.12.0 on 2026-09-22.

Configuration flows from the environment into LazySettings, then into the app registry, middleware list, URLConf, and connection handlers. An HTTP request becomes a request object, passes a middleware onion, resolves to a view, and returns an HttpResponse. ORM reads stay as Query objects until evaluation, then SQLCompiler sends SQL and params to a backend cursor. Writes go through Model.save_base and, for schema, through MigrationExecutor. Cross-cutting state (sessions, CSRF, signatures) is keyed by SECRET_KEY or server-side stores.
- WSGIHandler.__call__ sets the script prefix from the WSGI environ, sends request_started, builds a WSGIRequest (method, LimitedStream body capped at CONTENT_LENGTH, GET from QUERY_STRING, cookies from HTTP_COOKIE), then get_response. The iterable returned may be a wsgi.file_wrapper around response.file_to_stream. — [django/core/handlers/wsgi.py#L56-144](https://github.com/django/django/blob/dd6f6b1531984823e3dc56740dfa93f3ceb09357/django/core/handlers/wsgi.py#L56-L144)
- BaseHandler.load_middleware imports each settings.MIDDLEWARE path in reverse, instantiates it with the adapted next handler, and records process_view, process_template_response, and process_exception hooks. MiddlewareNotUsed skips an entry. get_response sets the thread URLConf to ROOT_URLCONF, runs the chain, and logs status >= 400. — [django/core/handlers/base.py#L27-152](https://github.com/django/django/blob/dd6f6b1531984823e3dc56740dfa93f3ceb09357/django/core/handlers/base.py#L27-L152)
- resolve_request uses request.urlconf if set, otherwise get_resolver(), then URLResolver.resolve(request.path_info). resolve walks url_patterns, merges kwargs, and returns a ResolverMatch. request_finished is connected to reset_urlconf. — [django/core/handlers/base.py#L302-317](https://github.com/django/django/blob/dd6f6b1531984823e3dc56740dfa93f3ceb09357/django/core/handlers/base.py#L302-L317) [django/urls/resolvers.py#L672-710](https://github.com/django/django/blob/dd6f6b1531984823e3dc56740dfa93f3ceb09357/django/urls/resolvers.py#L672-L710) [django/core/handlers/base.py#L370-375](https://github.com/django/django/blob/dd6f6b1531984823e3dc56740dfa93f3ceb09357/django/core/handlers/base.py#L370-L375)
- If the view returns an object with a callable render(), template-response middleware runs and then response.render() is called. A None or unawaited coroutine from a view raises ValueError. Async views on the sync path are wrapped with async_to_sync. — [django/core/handlers/base.py#L176-228](https://github.com/django/django/blob/dd6f6b1531984823e3dc56740dfa93f3ceb09357/django/core/handlers/base.py#L176-L228)
- QuerySet.filter clones via _chain and adds a Q object in _filter_or_exclude_inplace; it raises TypeError if the query is already sliced. Evaluation is deferred until _fetch_all, which lists self._iterable_class(self) and then runs prefetch_related if needed. — [django/db/models/query.py#L1723-1757](https://github.com/django/django/blob/dd6f6b1531984823e3dc56740dfa93f3ceb09357/django/db/models/query.py#L1723-L1757) [django/db/models/query.py#L2326-2330](https://github.com/django/django/blob/dd6f6b1531984823e3dc56740dfa93f3ceb09357/django/db/models/query.py#L2326-L2330)
- SQLCompiler.execute_sql compiles with as_sql(), opens connection.cursor() or chunked_cursor(), and calls cursor.execute(sql, params). Result shape depends on MULTI, SINGLE, ROW_COUNT, or CURSOR. EmptyResultSet short-circuits. — [django/db/models/sql/compiler.py#L1619-1649](https://github.com/django/django/blob/dd6f6b1531984823e3dc56740dfa93f3ceb09357/django/db/models/sql/compiler.py#L1619-L1649)
- Model.save picks a database with router.db_for_write, optionally narrows update_fields for deferred instances, then save_base sends pre_save, writes inside transaction.atomic (if the model has parents) or mark_for_rollback_on_error, stores _state.db, clears _state.adding, and sends post_save with created=(not updated). — [django/db/models/base.py#L847-1024](https://github.com/django/django/blob/dd6f6b1531984823e3dc56740dfa93f3ceb09357/django/db/models/base.py#L847-L1024)
- MigrationExecutor.migrate ensures the django_migrations table unless the plan is empty, builds a plan, rejects mixed forward and backward plans with InvalidMigrationPlan, and applies forward migrations in full_plan order via apply_migration. — [django/db/migrations/executor.py#L96-169](https://github.com/django/django/blob/dd6f6b1531984823e3dc56740dfa93f3ceb09357/django/db/migrations/executor.py#L96-L169)
- CSRF: CsrfViewMiddleware reads the secret from the session (CSRF_USE_SESSIONS, key requires SessionMiddleware first) or from cookie CSRF_COOKIE_NAME (default csrftoken). Unsafe methods must present csrfmiddlewaretoken in POST or the header named by CSRF_HEADER_NAME (default HTTP_X_CSRFTOKEN). Failures go to CSRF_FAILURE_VIEW. — [django/middleware/csrf.py#L165-268](https://github.com/django/django/blob/dd6f6b1531984823e3dc56740dfa93f3ceb09357/django/middleware/csrf.py#L165-L268) [django/middleware/csrf.py#L349-384](https://github.com/django/django/blob/dd6f6b1531984823e3dc56740dfa93f3ceb09357/django/middleware/csrf.py#L349-L384) [django/conf/global_settings.py#L567-585](https://github.com/django/django/blob/dd6f6b1531984823e3dc56740dfa93f3ceb09357/django/conf/global_settings.py#L567-L585)
- HttpRequest.get_host validates the raw host against ALLOWED_HOSTS via validate_host. If DEBUG is true and ALLOWED_HOSTS is empty, the allow-list becomes .localhost, 127.0.0.1, and [::1]. Otherwise it raises DisallowedHost. is_secure consults SECURE_PROXY_SSL_HEADER before the scheme. — [django/http/request.py#L190-210](https://github.com/django/django/blob/dd6f6b1531984823e3dc56740dfa93f3ceb09357/django/http/request.py#L190-L210) [django/http/request.py#L306-330](https://github.com/django/django/blob/dd6f6b1531984823e3dc56740dfa93f3ceb09357/django/http/request.py#L306-L330)
- Signed cookies: HttpRequest.get_signed_cookie calls signing._unsign_cookie and re-raises BadSignature unless a default is supplied. SIGNING_BACKEND defaults to django.core.signing.TimestampSigner. The signing module documents HMAC/SHA-256 over URL-safe base64 JSON using the project secret. — [django/http/request.py#L239-261](https://github.com/django/django/blob/dd6f6b1531984823e3dc56740dfa93f3ceb09357/django/http/request.py#L239-L261) [django/core/signing.py#L1-66](https://github.com/django/django/blob/dd6f6b1531984823e3dc56740dfa93f3ceb09357/django/core/signing.py#L1-L66) [django/conf/global_settings.py#L560-565](https://github.com/django/django/blob/dd6f6b1531984823e3dc56740dfa93f3ceb09357/django/conf/global_settings.py#L560-L565)
- Upload bounds in global settings: DATA_UPLOAD_MAX_MEMORY_SIZE and FILE_UPLOAD_MAX_MEMORY_SIZE are 2621440 bytes, DATA_UPLOAD_MAX_NUMBER_FIELDS is 1000, and DATA_UPLOAD_MAX_NUMBER_FILES is 100. WSGIRequest wraps wsgi.input in LimitedStream so reads cannot pass CONTENT_LENGTH. — [django/conf/global_settings.py#L311-330](https://github.com/django/django/blob/dd6f6b1531984823e3dc56740dfa93f3ceb09357/django/conf/global_settings.py#L311-L330) [django/core/handlers/wsgi.py#L15-40](https://github.com/django/django/blob/dd6f6b1531984823e3dc56740dfa93f3ceb09357/django/core/handlers/wsgi.py#L15-L40)
- ImmediateBackend.enqueue does not hand work to another process: _execute_task sets status RUNNING, calls task.call (async_to_sync if needed), JSON-normalizes the return value, and sets SUCCESSFUL or FAILED with a traceback stored on TaskResult.errors. — [django/tasks/backends/immediate.py#L24-80](https://github.com/django/django/blob/dd6f6b1531984823e3dc56740dfa93f3ceb09357/django/tasks/backends/immediate.py#L24-L80) [django/tasks/base.py#L131-138](https://github.com/django/django/blob/dd6f6b1531984823e3dc56740dfa93f3ceb09357/django/tasks/base.py#L131-L138)
- Settings reference order is explicit user module then global defaults. When MAILERS is defined, deprecated EMAIL_* names are rejected if also set, and getattr of those names is blocked. Database routers are an ordered list in DATABASE_ROUTERS, empty by default. — [django/conf/__init__.py#L60-70](https://github.com/django/django/blob/dd6f6b1531984823e3dc56740dfa93f3ceb09357/django/conf/__init__.py#L60-L70) [django/conf/__init__.py#L128-192](https://github.com/django/django/blob/dd6f6b1531984823e3dc56740dfa93f3ceb09357/django/conf/__init__.py#L128-L192) [django/conf/global_settings.py#L184-189](https://github.com/django/django/blob/dd6f6b1531984823e3dc56740dfa93f3ceb09357/django/conf/global_settings.py#L184-L189)

Every claim links to its cited files at the pinned commit. Citations identify source evidence; they do not establish runtime correctness. Independent CodeVetter scan — not reviewed by upstream maintainers.

## Public product links

- [CodeVetter](https://codevetter.com/)
- [Download](https://codevetter.com/download)
- [Documentation](https://codevetter.com/docs/)
- [Source](https://github.com/Codevetter/codevetter)
