How to manage local vs production settings in Django?
Rise to the top 3% as a developer or hire one of them at Toptal: https://topt.al/25cXVn
--------------------------------------------------
Music by Eric Matyas
https://www.soundimage.org
Track title: Quirky Dreamscape Looping
--
Chapters
00:00 How To Manage Local Vs Production Settings In Django?
00:47 Answer 1 Score 20
01:37 Accepted Answer Score 136
01:57 Answer 3 Score 76
03:19 Answer 4 Score 331
04:18 Thank you
--
Full question
https://stackoverflow.com/questions/1626...
--
Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...
--
Tags
#python #django #deployment
#avk47
ANSWER 1
Score 331
Two Scoops of Django: Best Practices for Django 1.5 suggests using version control for your settings files and storing the files in a separate directory:
project/
    app1/
    app2/
    project/
        __init__.py
        settings/
            __init__.py
            base.py
            local.py
            production.py
    manage.py
The base.py file contains common settings (such as MEDIA_ROOT or ADMIN), while local.py and production.py have site-specific settings:
In the base file settings/base.py:
INSTALLED_APPS = (
    # common apps...
)
In the local development settings file settings/local.py:
from project.settings.base import *
DEBUG = True
INSTALLED_APPS += (
    'debug_toolbar', # and other apps for local development
)
In the file production settings file settings/production.py:
from project.settings.base import *
DEBUG = False
INSTALLED_APPS += (
    # other apps for production site
)
Then when you run django, you add the --settings option:
# Running django for local development
$ ./manage.py runserver 0:8000 --settings=project.settings.local
# Running django shell on the production site
$ ./manage.py shell --settings=project.settings.production
The authors of the book have also put up a sample project layout template on Github.
ACCEPTED ANSWER
Score 136
In settings.py:
try:
    from local_settings import *
except ImportError as e:
    pass
You can override what needed in local_settings.py; it should stay out of your version control then. But since you mention copying I'm guessing you use none ;)
ANSWER 3
Score 76
Instead of settings.py, use this layout:
.
└── settings/
    ├── __init__.py  <= not versioned
    ├── common.py
    ├── dev.py
    └── prod.py
common.py is where most of your configuration lives.
prod.py imports everything from common, and overrides whatever it needs to override:
from __future__ import absolute_import # optional, but I like it
from .common import *
# Production overrides
DEBUG = False
#...
Similarly, dev.py imports everything from common.py and overrides whatever it needs to override.
Finally, __init__.py is where you decide which settings to load, and it's also where you store secrets (therefore this file should not be versioned):
from __future__ import absolute_import
from .prod import *  # or .dev if you want dev
##### DJANGO SECRETS
SECRET_KEY = '(3gd6shenud@&57...'
DATABASES['default']['PASSWORD'] = 'f9kGH...'
##### OTHER SECRETS
AWS_SECRET_ACCESS_KEY = "h50fH..."
What I like about this solution is:
- Everything is in your versioning system, except secrets
 - Most configuration is in one place: 
common.py. - Prod-specific things go in 
prod.py, dev-specific things go indev.py. It's simple. - You can override stuff from 
common.pyinprod.pyordev.py, and you can override anything in__init__.py. - It's straightforward python. No re-import hacks.
 
ANSWER 4
Score 20
I use a slightly modified version of the "if DEBUG" style of settings that Harper Shelby posted. Obviously depending on the environment (win/linux/etc.) the code might need to be tweaked a bit.
I was in the past using the "if DEBUG" but I found that occasionally I needed to do testing with DEUBG set to False. What I really wanted to distinguish if the environment was production or development, which gave me the freedom to choose the DEBUG level.
PRODUCTION_SERVERS = ['WEBSERVER1','WEBSERVER2',]
if os.environ['COMPUTERNAME'] in PRODUCTION_SERVERS:
    PRODUCTION = True
else:
    PRODUCTION = False
DEBUG = not PRODUCTION
TEMPLATE_DEBUG = DEBUG
# ...
if PRODUCTION:
    DATABASE_HOST = '192.168.1.1'
else:
    DATABASE_HOST = 'localhost'
I'd still consider this way of settings a work in progress. I haven't seen any one way to handling Django settings that covered all the bases and at the same time wasn't a total hassle to setup (I'm not down with the 5x settings files methods).