Django settings for multiple environments
Update Just read Two Scoops of Django
After you create your project, create a settings
directory under your project and copy settings.py
to settings/defaults.py
-- you don't have to use the name defaults.py
(some people prefer common.py
) but for this example that's what I'll use.
Then, create settings/__init__.py
and a file for each environment. Your project should look mostly like this:
top-folder-named-whatever-you-like
- manage.py
- requirements.txt
- myproject/
- __init__.py
- urls.py
- wsgi.py
- myapp/
- __init__.py
- models.py
- tests.py
- views.py
- static/
- templates/
- templatetags/
- settings/
- __init__.py
- defaults.py
- production.py # from defaults import *
- staging.py # ditto
- development.example.py # ditto
- development.py # not in git
Obviously everyone doesn't set their project up the same way, so there may be some differences. That's fine as long as the settings folder has a file for each environment.
Tell git to ignore development.py
(or local.py
if you call it that). But create an example file to help other developers get set up quickly.
At the top of each of your environment settings files, add an import to get the default settings.
Now is the tricky part as there are many ways to set the DJANGO_SETTINGS_MODEL
environment variable.
Remotely, it's more straightforward. You can put it in your vhost if you're on Apache, and I'm sure there's a similar way with nginx. There are other ways involving declaring it in the same command that runs your wsgi. However you do it, if you're on, say, production, you'll want it set to myproject.settings.production
.
Locally, you want to set it to myproject.settings.development
. You used to be able to put DJANGO_SETTINGS_MODULE=settings.development
in your .bashrc. But since Django changed the default layout, you now have to include the project name in the settings path.
The obvious, but most likely to fail solution is to remember to set it on the command line in every terminal session in which you're working on your project.
A hacky way is to copy manage.py
to manage_local.py
(ignored by git) and edit it to use myproject.settings.development
instead of just myproject.settings
. Then remember to use manage_local.py
instead of manage.py
A professional but verbose way is to use Foreman, a Procfile, and a .env file which holds your environment variables. If you have more environment variables to set, or if you are deploying to heroku, you might as well do it this way.
Here's a good article on using Foreman locally: http://avalonstar.com/journal/2012/jan/01/on-foreman-and-procfiles/
Update I'm working on a fabfile using the development version of Fabric that will allow you to run commands like fab web
and fab shell
and fab manage:somecommand
with DJANGO_SETTINGS_MODULE
as set in a .env
file which can also be used with Foreman.
Written by katy lavallee
Related protips
1 Response
Small typo ... you said DJANGOSETTINGSMODEL in the first mention of the env var. Another way that you did not mention is to pass in --settings=myproject.settings.production
etc at the end of management commands that you would want to run in a different env. e.g. ./manage,py syncdb --settings=myproject.settings.production