Django: How to manage development and production settings?
This is how I do it in 6 easy steps:
Create a folder inside your project directory and name it
settings
.Project structure:
myproject/ myapp1/ myapp2/ myproject/ settings/
Create four python files inside of the
settings
directory namely__init__.py
,base.py
,dev.py
andprod.py
Settings files:
settings/ __init__.py base.py prod.py dev.py
Open
__init__.py
and fill it with the following content:init.py:
from .base import * # you need to set "myproject = 'prod'" as an environment variable # in your OS (on which your website is hosted) if os.environ['myproject'] == 'prod': from .prod import * else: from .dev import *
Open
base.py
and fill it with all the common settings (that will be used in both production as well as development.) for example:base.py:
import os ... INSTALLED_APPS = [...] MIDDLEWARE = [...] TEMPLATES = [{...}] ... STATIC_URL = '/static/' STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles') MEDIA_ROOT = os.path.join(BASE_DIR, '/path/') MEDIA_URL = '/path/'
Open
dev.py
and include that stuff which is development specific for example:dev.py:
DEBUG = True ALLOWED_HOSTS = ['localhost'] ...
Open
prod.py
and include that stuff which is production specific for example:prod.py:
DEBUG = False ALLOWED_HOSTS = ['www.example.com'] LOGGING = [...] ...
Update
As ANDRESMA suggested in comments. Update BASE_DIR
in your base.py
file to reflect your updated path by adding another .parent
to the end. For example:
BASE_DIR = Path(__file__).resolve().parent.parent.parent
By default use production settings, but create a file called settings_dev.py
in the same folder as your settings.py
file. Add overrides there, such as DEBUG=True
.
On the computer that will be used for development, add this to your ~/.bashrc
file:
export DJANGO_DEVELOPMENT=true
At the bottom of your settings.py
file, add the following.
# Override production variables if DJANGO_DEVELOPMENT env variable is set
if os.environ.get('DJANGO_DEVELOPMENT'):
from settings_dev import * # or specific overrides
(Note that importing *
should generally be avoided in Python)
By default the production servers will not override anything. Done!
Compared to the other answers, this one is simpler because it doesn't require updating PYTHONPATH
, or setting DJANGO_SETTINGS_MODULE
which only allows you to work on one django project at a time.
I usually have one settings file per environment, and a shared settings file:
/myproject/
settings.production.py
settings.development.py
shared_settings.py
Each of my environment files has:
try:
from shared_settings import *
except ImportError:
pass
This allows me to override shared settings if necessary (by adding the modifications below that stanza).
I then select which settings files to use by linking it in to settings.py:
ln -s settings.development.py settings.py
The DJANGO_SETTINGS_MODULE
environment variable controls which settings file Django will load.
You therefore create separate configuration files for your respective environments (note that they can of course both import *
from a separate, "shared settings" file), and use DJANGO_SETTINGS_MODULE
to control which one to use.
Here's how:
As noted in the Django documentation:
The value of DJANGO_SETTINGS_MODULE should be in Python path syntax, e.g. mysite.settings. Note that the settings module should be on the Python import search path.
So, let's assume you created myapp/production_settings.py
and myapp/test_settings.py
in your source repository.
In that case, you'd respectively set DJANGO_SETTINGS_MODULE=myapp.production_settings
to use the former and DJANGO_SETTINGS_MODULE=myapp.test_settings
to use the latter.
From here on out, the problem boils down to setting the DJANGO_SETTINGS_MODULE
environment variable.
Setting DJANGO_SETTINGS_MODULE
using a script or a shell
You can then use a bootstrap script or a process manager to load the correct settings (by setting the environment), or just run it from your shell before starting Django: export DJANGO_SETTINGS_MODULE=myapp.production_settings
.
Note that you can run this export at any time from a shell — it does not need to live in your .bashrc
or anything.
Setting DJANGO_SETTINGS_MODULE
using a Process Manager
If you're not fond of writing a bootstrap script that sets the environment (and there are very good reasons to feel that way!), I would recommend using a process manager:
- Supervisor lets you pass environment variables to managed processes using a program's
environment
configuration key. - Honcho (a pure-Python equivalent of Ruby's Foreman) lets you define environment variables in an "environment" (
.env
) file.
Finally, note that you can take advantage of the PYTHONPATH
variable to store the settings in a completely different location (e.g. on a production server, storing them in /etc/
). This allows for separating configuration from application files. You may or may not want that, it depends on how your app is structured.