Django How to manage development and production settings?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
The safest way to manage Django settings is to keep shared defaults in one place and isolate environment-specific behavior behind separate settings modules. That gives you clear control over DEBUG, database credentials, allowed hosts, and service integrations without copying one huge settings file across development and production.
Split settings into base, development, and production
A common project layout looks like this:
base.py should hold the settings that are truly common across all environments, such as installed apps, middleware, templates, and the default time zone.
Then keep local-only behavior in development.py:
And production-only behavior in production.py:
This structure makes the differences obvious and prevents accidental production behavior from leaking into local development.
Select the active settings module explicitly
Django loads whichever module DJANGO_SETTINGS_MODULE points to. That means your environment selection should be explicit at process startup.
For local development:
For production:
This is much cleaner than trying to detect the environment indirectly inside one giant settings file.
Put secrets in environment variables, not in Git
Do not hardcode production secrets into production.py. The settings module should define how to read secrets, not embed them directly. Environment variables are the simplest default and work well with Docker, Kubernetes, systemd, and most cloud platforms.
If you want cleaner parsing, packages such as django-environ can help, but the core rule remains the same: version-control the structure, not the secret values.
The same applies to service credentials for Redis, S3, email, and external APIs. Keep the interface in settings, but inject real values from the runtime environment.
Keep behavior differences deliberate
Not every setting belongs in every file. For example:
- '
DEBUGshould differ' - database settings often differ
- cache backend may differ
- logging usually differs
- security flags should be strongest in production
What should stay shared is the application shape. Installed apps, middleware ordering, and template configuration usually belong in base.py unless there is a specific reason to diverge.
That balance keeps the code understandable. If too much logic is duplicated between development and production modules, the split stops helping.
Common Pitfalls
- Keeping one giant settings file with
ifbranches everywhere instead of using separate settings modules. - Committing production secrets directly into the repository.
- Forgetting to set
DJANGO_SETTINGS_MODULEexplicitly and accidentally starting with the wrong environment. - Copying large blocks of settings between development and production until they drift out of sync.
- Enabling
DEBUGor weak security flags in production because local defaults leaked into deployment.
Summary
- Use a shared
base.pyplus environment-specific modules such asdevelopment.pyandproduction.py. - Select the active module with
DJANGO_SETTINGS_MODULE. - Read secrets from environment variables rather than hardcoding them in settings files.
- Keep common application structure in
base.pyand only isolate true environment differences. - The main goal is clarity: each environment should be explicit, reviewable, and hard to misuse.

