Open-Source Wikis

/

Django

/

Systems

/

Apps and settings

django/django

Apps and settings

Two small modules that almost everything else depends on: django/apps/ (the app registry) and django/conf/ (the settings lazy object). Together they own startup configuration and runtime introspection.

Purpose

django/conf/ exposes a global settings object that lazy-loads the project's settings module on first access. django/apps/ walks INSTALLED_APPS and produces an AppRegistry that other subsystems consult to find apps, models, and metadata.

Settings (django/conf/)

django/conf/
├── __init__.py        # LazySettings, Settings, UserSettingsHolder, settings global
├── global_settings.py # the defaults (DEBUG, INSTALLED_APPS, MIDDLEWARE, …)
├── locale/            # built-in language catalogs
├── project_template/  # files copied by `startproject`
├── app_template/      # files copied by `startapp`
└── urls/              # default URLconfs (i18n, static)

LazySettings

The public settings object is a LazySettings instance:

from django.conf import settings
settings.DEBUG  # triggers lazy load

On first attribute access, LazySettings._setup():

  1. Reads DJANGO_SETTINGS_MODULE from the environment.
  2. Imports that module.
  3. Wraps it in a Settings instance, which:
    • Copies all uppercase attributes from the module.
    • Applies the defaults from global_settings.py for anything missing.
    • Validates a few critical settings (SECRET_KEY non-empty, DEFAULT_HASHING_ALGORITHM, etc.).

settings.configure(...) is the alternative for projects that don't have a settings module — useful in scripts and the test suite. It accepts default_settings and any number of overrides.

setting_changed signal

django/test/signals.py defines a setting_changed signal that fires whenever override_settings (or settings.configure(**kwargs) from a test) changes a setting at runtime. Many subsystems listen so they can rebuild caches:

  • The URL resolver clears its caches when ROOT_URLCONF changes.
  • The template engine rebuilds when TEMPLATES changes.
  • The cache backend reconfigures when CACHES changes.

This signal is not part of the public API for production use — runtime setting changes are a testing convenience.

global_settings.py

The defaults file declares roughly 200 settings, each with a default value and (in the docs) a description. Highlights:

  • INSTALLED_APPS = [] — no apps unless the user adds them.
  • MIDDLEWARE = [] — no middleware unless the user adds them.
  • DATABASES = {} — empty; must be configured.
  • TEMPLATES = [] — empty; must be configured if templates are used.
  • DEBUG = False — production-safe default.
  • ALLOWED_HOSTS = [] — empty; required when DEBUG = False.
  • SECRET_KEY = "" — empty by default; checked at startup.

The file is the canonical reference for "what settings exist". Adding a new setting means adding a default here.

Apps registry (django/apps/)

django/apps/
├── __init__.py       # exports apps (the singleton registry)
├── registry.py       # AppRegistry: the registry class
└── config.py         # AppConfig: the per-app metadata object

AppRegistry

A singleton (instantiated as apps) that tracks:

  • The list of installed apps in load order.
  • For each app, an AppConfig instance.
  • For each app, a dictionary of models keyed by model name.
  • A flag indicating whether the registry is "ready" (populated).

The registry is populated by apps.populate(installed_apps), which is called from django.setup() in django/__init__.py. Population walks INSTALLED_APPS:

  1. For each entry, find the AppConfig (either explicitly via <dotted.path>.<AppConfig name> or implicitly by importing the package and looking for the default config).
  2. Import the app's models module (this triggers Model.__init_subclass__, which calls apps.register_model).
  3. Once all models are registered, call each AppConfig.ready() hook.

apps.ready is the flag that gates the rest of the framework — model lookups before populate() raises AppRegistryNotReady.

AppConfig

The per-app metadata object:

Attribute What it means
name Dotted Python path (django.contrib.auth)
label Short label (auth); used in many APIs as the app's identity
verbose_name Human-readable name (used by the admin)
path Filesystem path of the app
models_module The imported models module, if any
default_auto_field The default *Field for primary keys (overrides DEFAULT_AUTO_FIELD)
ready() Hook called after registry population — used to wire signals

Apps that need post-load setup (e.g., contenttypes connecting to post_migrate) put it in ready().

Model lookup

Public lookup methods on the registry:

  • apps.get_app_config(label)AppConfig by label.
  • apps.get_app_configs() — all configs.
  • apps.get_model(app_label, model_name) — model class by app + name.
  • apps.get_model("auth.User") — same, dotted form.
  • apps.get_models() — every model in every app.

The ORM uses apps.get_model("auth.User") to resolve string references to swappable models. Migrations use the registry to build ProjectState snapshots.

How they fit together

graph TD
    Env["DJANGO_SETTINGS_MODULE"]
    Settings["LazySettings (django.conf.settings)"]
    Setup["django.setup()"]
    Apps["AppRegistry (django.apps.apps)"]
    Models["registered Model classes"]
    URL["URL resolver"]
    ORM["ORM"]
    Admin["admin.autodiscover()"]

    Env --> Settings
    Settings -->|INSTALLED_APPS| Setup
    Setup --> Apps
    Apps --> Models
    Models --> ORM
    Apps --> URL
    Apps --> Admin

django.setup() (in django/__init__.py) is the bootstrap. WSGI/ASGI handlers call it implicitly. Management commands call it after parsing settings.

Signals from the apps registry

  • apps_loaded_signal (internal; not stable public API) — fires after populate() finishes.
  • class_prepared (django/db/models/signals.py) — fires as each model class is created.
  • pre_migrate / post_migrate (django/db/models/signals.py) — fired by the migrate command but anchored by app config.

Integration points

  • Every other subsystem reads from django.conf import settings.
  • The ORM uses the registry for swappable model resolution.
  • The admin calls apps.get_app_configs() during autodiscover.
  • Migrations consume apps.all_models to build ProjectState.
  • System checks are registered per-app (some use AppConfig.ready to register).
  • Templates use apps.get_app_configs() to find <app>/templates/ directories (via app_directories.Loader).

Entry points for modification

  • New default setting: add to django/conf/global_settings.py. Document in docs/ref/settings.txt.
  • New AppConfig attribute: add to django/apps/config.py. Subsystems that care can read it.
  • Custom app loading: subclass AppConfig and reference it in INSTALLED_APPS as "my.app.MyAppConfig".
  • Hook into populate: implement ready() on your AppConfig and connect signals there.

Key source files

File Purpose
django/conf/__init__.py LazySettings, Settings, UserSettingsHolder
django/conf/global_settings.py Default values for every setting
django/apps/registry.py AppRegistry
django/apps/config.py AppConfig
django/__init__.py setup() (the bootstrap)
django/test/signals.py setting_changed

Where to read tests

  • tests/settings_tests/LazySettings, override_settings, configure.
  • tests/apps/AppRegistry, AppConfig, populate.
  • tests/check_framework/ — system checks against settings shape.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Apps and settings – Django wiki | Factory