CodeVetter · Repo Unpack · Behavior traces
django/django
Three flows dominate day-to-day work: process startup for django-admin, the per-request path from handler to view, and the persistence path from QuerySet or Model.save through SQL and migrations. Auth and CSRF are the security-critical variants of the request path. Names below are the functions actually called, in order.
- CLI startup order: execute_from_command_line -> ManagementUtility.execute -> CommandParser known-args for --settings/--pythonpath -> handle_default_options -> django.setup (configure_logging, set_script_prefix, apps.populate) -> autocomplete if DJANGO_AUTO_COMPLETE is set -> fetch_command -> load_command_class -> BaseCommand.run_from_argv -> execute (system checks unless skipped) -> Command.handle. No subcommand prints help.
- runserver special case: if the subcommand is runserver and --noreload is absent, ManagementUtility calls autoreload.check_errors(django.setup) before the command class is loaded, and on failure pretends the app registry is ready so the reloader child can show the exception. Command.handle then inner_run via run_with_reloader, serving get_internal_wsgi_application().
- Sync HTTP order: WSGIHandler.__call__ -> signals.request_started (reset_queries, close_old_connections) -> WSGIRequest -> BaseHandler.get_response -> set_urlconf(ROOT_URLCONF) -> middleware chain -> _get_response -> resolve_request -> URLResolver.resolve -> make_view_atomic -> view(request, *args, **kwargs) -> optional process_exception -> optional TemplateResponse.render -> start_response.
- ASGI differs at the edges: ASGIHandler serves ASGIRequest built from scope (path, method, query_string, root_path) and uses get_response_async so async views are awaited and sync views run via sync_to_async(thread_sensitive=True). body_receive_timeout is 60 seconds.
- Class-based view order: URL resolver calls the callable returned by View.as_view -> view() constructs the class, calls setup (stores request/args/kwargs, aliases head to get), then dispatch, which lowercases request.method and invokes that handler or http_method_not_allowed.
- Read query order: QuerySet.filter -> _filter_or_exclude -> _chain/_clone -> _filter_or_exclude_inplace -> Query.add_q(Q). Later iteration calls _fetch_all -> ModelIterable -> SQL compiler as_sql -> SQLCompiler.execute_sql -> cursor.execute. prefetch_related runs only after the primary result list exists.
- Write order: Model.save -> _prepare_related_fields_for_save -> router.db_for_write -> save_base -> pre_save.send -> _save_parents (when not raw) -> _save_table -> _do_insert or _do_update -> post_save.send. asave is sync_to_async(self.save). Empty update_fields returns before signals.
- migrate command order: Command.handle reads --database (default alias), builds a MigrationExecutor for that connection, plans targets, and calls executor.migrate. Forward application renders project state (state.apps) once, then apply_migration for each selected node. --fake records without running SQL.
- Login order: authenticate walks AUTHENTICATION_BACKENDS, calls backend.authenticate, stops on PermissionDenied, and on total failure sends user_login_failed. ModelBackend.authenticate loads the user with get_by_natural_key and check_password_with_timing_attack_mitigation, then user_can_authenticate (is_active). login() stores the user pk and session auth hash, flushing the session if it belonged to someone else, otherwise cycle_key.
- CSRF failure order on an unsafe request: process_view -> _get_secret (cookie or session) -> _check_token compares the POST or header token -> RejectRequest -> _reject -> CSRF_FAILURE_VIEW (default django.views.csrf.csrf_failure) -> log_response Forbidden. HTTPS requests also pass _origin_verified and _check_referer.
- Password check order: check_password -> verify_password -> identify_hasher (algorithm is the prefix before $, with legacy unsalted md5/sha1 shapes) -> hasher.verify. If the preferred hasher differs or must_update, and a setter is passed, the password is re-encoded. Missing users still run make_password once to reduce timing differences.
- System-check order inside a command: BaseCommand.execute, when requires_system_checks and not skip_checks, calls self.check, then check_migrations if required, then handle. call_command forces skip_checks=True unless the caller passed that option. Deployment-tagged checks such as check_secret_key are omitted unless include_deployment_checks is set.