How to manage local vs production settings in Django?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Django settings should differ between local development and production, but the differences need to stay controlled and predictable. The safest pattern is to keep shared defaults in one base settings module, load environment-specific values from separate files or environment variables, and never hardcode secrets or deployment-only behavior into the development setup.
Split Shared and Environment-Specific Settings
A common project structure is:
base.py contains settings shared by every environment, while local.py and production.py override only what differs.
Example base.py:
This keeps the common baseline in one place.
Override Only What Really Changes
Local development and production usually differ in a few predictable areas:
- '
DEBUG' - database connection
- allowed hosts
- static/media storage
- secret values
- logging verbosity
Example local.py:
Example production.py:
Notice that production values come from environment variables rather than from committed source.
Select the Settings Module Explicitly
Django chooses its settings module from DJANGO_SETTINGS_MODULE. That means each environment should start the app with the right module name.
For production:
Being explicit here prevents a large class of deployment mistakes.
Keep Secrets Out of Version Control
Secret keys, database passwords, API tokens, and similar values should not live in committed settings files. Use environment variables or a secrets manager instead.
A simple example:
This is safer and also makes deployment automation easier because credentials can change without changing source files.
Use Packages Only When They Simplify the Setup
Libraries such as django-environ can make environment variable parsing more convenient, but they are helpful only if they actually simplify the project. The core design principle remains the same with or without a helper package: shared defaults in one place, environment-specific overrides elsewhere, secrets outside source control.
Avoid Big Divergence Between Environments
Local and production should differ where necessary, but not in arbitrary ways. If the local stack uses SQLite and production uses PostgreSQL, that may be acceptable for a small project, but it can also hide database-specific behavior until deployment.
The more your environments diverge, the more surprises you invite. Use lightweight differences for convenience, but keep important behavior aligned whenever possible.
Common Pitfalls
- Keeping all settings in one file and scattering
if DEBUGlogic everywhere. - Committing secrets into source-controlled settings files.
- Forgetting to set
DJANGO_SETTINGS_MODULEcorrectly in deployment. - Letting local and production databases behave too differently without realizing the tradeoff.
- Duplicating large blocks of settings instead of inheriting from a shared base.
Summary
- Put shared Django settings in a base module and environment-specific overrides in separate files.
- Use environment variables for secrets and deployment-specific values.
- Select the correct settings module explicitly with
DJANGO_SETTINGS_MODULE. - Override only what really differs between local and production.
- Keep the environments aligned enough that deployment behavior does not become a surprise.

