Challenge 1: Write Environment-Driven Settings — Possible Solution ==================================================================== # BEFORE — hardcoded, unsafe for source control DEBUG = True SECRET_KEY = "django-insecure-abc123hardcodedsecretkey" ALLOWED_HOSTS = [] # AFTER — settings.py import os DEBUG = os.environ.get("DJANGO_DEBUG", "False") == "True" # Fails fast with a clear KeyError if DJANGO_SECRET_KEY isn't set at all — # better to crash loudly on startup than silently run with no secret key. SECRET_KEY = os.environ["DJANGO_SECRET_KEY"] ALLOWED_HOSTS = [ host.strip() for host in os.environ.get("DJANGO_ALLOWED_HOSTS", "").split(",") if host.strip() ] # .env (local development only — NEVER committed to source control) DJANGO_DEBUG=True DJANGO_SECRET_KEY=a-different-random-secret-for-local-dev-only DJANGO_ALLOWED_HOSTS=localhost,127.0.0.1 # .gitignore .env WHY THIS WORKS -------------- - DEBUG now defaults to "False" (as a string comparison) if DJANGO_DEBUG isn't set at all — meaning an environment that forgets to configure it explicitly fails SAFE (debug mode off) rather than failing open, which is the opposite of the risky default from the original hardcoded version. - SECRET_KEY = os.environ["DJANGO_SECRET_KEY"] uses direct dictionary indexing (not .get()) specifically so a missing environment variable raises a KeyError immediately when Django starts up — the app refuses to even boot without a real secret key configured, rather than silently falling back to some default or empty value. - ALLOWED_HOSTS is parsed from a comma-separated string environment variable into a proper Python list, with .strip() and a filter to ignore empty entries — this lets the same settings.py work correctly whether ALLOWED_HOSTS has one host or several, configured entirely outside the code. - The .env file (used only for local development, loaded via a tool like python-dotenv or django-environ) is explicitly .gitignore'd — this is the same discipline the TypeScript course's Configuration Management chapter taught: local secrets live in an untracked file, with only a documented .env.example (not shown here, but the standard companion) committed to source control.