Settings & Configuration

EarthRanger’s Django configuration is layered. Knowing which file a setting belongs in is the difference between a value that’s configurable in production and one that silently can’t be changed without a code release. This page is the single source of truth for where a new setting goes; for runtime feature toggles (per-tenant flags, admin kill switches) see Feature Flags.

The settings files

File

Purpose

das/das_server/settings.py

Base settings, and the home for all environment-driven settings. Reads env vars via env.bool(...) / env.str(...) / env.int(...)env is configured at the top of the file from django-environ.

das/das_server/local_settings_docker.py

Overrides specific to the Kubernetes production / Docker-compose environment that are not driven by env vars. Predates the project’s django-environ adoption and is not the default home for new settings.

das/test_scripts/unittest_settings.py

Test-only overrides. Imports local_settings_docker first, then forces specific values needed for the test suite.

.env (project root, git-ignored)

Local-development environment variables. django-environ loads it automatically via environ.Env.read_env(...).

DJANGO_SETTINGS_MODULE selects which module is active; DEBUG / DEV toggle development mode.

Where does my new setting go?

  • Configurable from the environment (12-factor)settings.py with env.bool("MY_SETTING", <default>).

  • A fixed, hardcoded default that callers never override at runtimesettings.py as MY_SETTING = <value>.

  • Different value under Kubernetes/Docker than in dev, and not exposed as an env varlocal_settings_docker.py.

  • A forced value needed only for the test suite to passtest_scripts/unittest_settings.py.

One source of truth per setting

Do not declare the same setting in both settings.py and local_settings_docker.py. That was the old pre-django-environ workaround and it creates two sources of truth. Some older settings (e.g. PATROL_ENABLED) still live in local_settings_docker.py for historical reasons — do not treat them as precedent. New env-driven settings go in settings.py.

Example

# das_server/settings.py
ENABLE_SILK = env.bool("ENABLE_SILK", False)          # env-driven, defaults off

# test_scripts/unittest_settings.py
ENABLE_SILK = False                                    # forced off for the test suite

Tenant-scoped settings, caches, and querysets

A handful of settings-adjacent concerns are tenant-aware and have their own rules — read Multi-Tenancy before working in these areas:

  • Tenant-scoped querysets in admin/form classes must be rebuilt per-request (in __init__ / get_queryset / formfield_for_*), never declared with a live tenant-scoped queryset at class/import time.

  • Cache aliases configured with KEY_FUNCTION: utils.tenant.cache.make_cache_key automatically prefix every key with the thread-local tenant ID — do not add an explicit tenant_id to the key yourself.

See also

  • Feature Flags — runtime toggles: per-tenant release toggles, the registry, and the global override used to gate Django admin pages. (Toggles are not Django settings — that page explains why.)

  • Multi-Tenancy — tenant isolation, threadlocal tenant context, and tenant-scoped caches.