Multiple Settings Files

Split settings into base, dev, staging, and prod. Learn import patterns, SECRET_KEY handling, debug flags, database overrides, and how to run with --settings or environment variables.

1. Introduction

A single settings.py file works fine when you are learning, but real projects need different configurations for different environments. Your development machine needs DEBUG = True and a local database. Your production server needs DEBUG = False, a real database, and secure keys loaded from environment variables.

The standard solution is to split your settings into multiple files — a base file with shared settings, and separate files for each environment that extend it.

  • You should already have myproject set up with a working mysite/settings.py.
  • Your .venv must be active and Django 5.2 installed.

2. The problem with one settings file

With a single settings file, developers often end up doing one of these:

  • Manually changing DEBUG and database settings before deploying — and forgetting to change them back.
  • Committing SECRET_KEY and database passwords to Git.
  • Using if statements inside settings.py to switch between environments — which gets messy fast.

3. The settings folder structure

Instead of a single settings.py file, we create a settings/ folder inside mysite with separate files for each environment:

myproject/
├── .venv/
├── manage.py
├── requirements.txt
└── mysite/
    ├── __init__.py
    ├── urls.py
    ├── asgi.py
    ├── wsgi.py
    └── settings/
        ├── __init__.py
        ├── base.py
        ├── dev.py
        └── prod.py
  • base.py — shared settings that apply to all environments.
  • dev.py — development-specific settings that override or extend base.
  • prod.py — production-specific settings that override or extend base.

4. Set it up step by step

Step 1 — Create the settings folder

mkdir mysite/settings
touch mysite/settings/__init__.py

Step 2 — Move and rename settings.py to base.py

mv mysite/settings.py mysite/settings/base.py

Step 3 — Create dev.py

dev.py imports everything from base.py and overrides what needs to be different in development:

# mysite/settings/dev.py

from .base import *

DEBUG = True

ALLOWED_HOSTS = ['127.0.0.1', 'localhost']

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}

Step 4 — Create prod.py

prod.py also imports from base.py but uses stricter settings for production:

# mysite/settings/prod.py

from .base import *
import os

DEBUG = False

SECRET_KEY = os.environ['SECRET_KEY']

ALLOWED_HOSTS = ['yourdomain.com', 'www.yourdomain.com']

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': os.environ['DB_NAME'],
        'USER': os.environ['DB_USER'],
        'PASSWORD': os.environ['DB_PASSWORD'],
        'HOST': os.environ['DB_HOST'],
        'PORT': os.environ.get('DB_PORT', '5432'),
    }
}

5. Tell Django which settings file to use

You need to update manage.py and mysite/wsgi.py to point to the new settings location.

Update manage.py

# manage.py
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mysite.settings.dev')

Update wsgi.py

# mysite/wsgi.py
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mysite.settings.prod')

Alternatively, you can pass the settings file directly when running a command:

# Use dev settings
python manage.py runserver --settings=mysite.settings.dev

# Use prod settings
python manage.py check --settings=mysite.settings.prod

6. What stays in base.py

base.py should only contain settings that are the same across all environments. A good rule: if a value changes between dev and prod, it does not belong in base.py.

Stays in base.py:

  • BASE_DIR
  • INSTALLED_APPS
  • MIDDLEWARE
  • TEMPLATES
  • AUTH_PASSWORD_VALIDATORS
  • LANGUAGE_CODE, TIME_ZONE, USE_TZ

Moves to dev.py or prod.py:

  • DEBUG
  • SECRET_KEY
  • ALLOWED_HOSTS
  • DATABASES

7. Next steps

Your settings are now split cleanly across environments. The next step is to load sensitive values like SECRET_KEY and database passwords from environment variables so they never end up in your codebase or Git history.


Never miss a story on Django.wiki

Subscribe for fresh tutorials, snippets, and updates.

By subscribing you agree to our Privacy Policy.