Manage Django Development and Production Settings

Contents

While django makes it easy to get an application up and running locally, the default setting is unsuitible for production use. It is a good practice to break down the default settings.py module into multiple files to seperate development settings and production settings.

An empty new django site looks like this:

1
2
3
4
5
6
7
mysite/
 |-- mysite/
 |    |-- __init__.py
 |    |-- settings.py
 |    |-- urls.py
 |    +-- wsgi.py
 +-- manage.py

We want to group different setting files together. So create a folder named settings, rename the settings.py file to base.py and move it into the newly created settings folder. Then we can create dev.py and production.py for development and production settings resepctively. Now the file structure would look like this:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
mysite/
|-- mysite/
|    |-- __init__.py
|    |-- settings/
|    |    |-- __init__.py
|    |    |-- base.py
|    |    |-- dev.py
|    |    |-- production.py
|    |    +-- staging.py
|    |-- urls.py
|    +-- wsgi.py
+-- manage.py

The settings/base.py file has all common settings in it. Other settings just extend base.py module like this:

1
2
3
4
# settings/dev.py
from .base import *

DEBUG = True

And production.py module usually read senstive infomation like SECRET_KEY from environment variable or local .env file.

1
2
3
4
5
6
# settings/production.py
from .base import *

DEBUG = False
env = os.environ.copy()
SECRET_KEY = env['SECRET_KEY']

We can pass which settings.py module to use in the coomand line when we start manage.py:

1
2
3
python manage.py runserver --settings=mysite.settings.dev

python manage.py runserver --settings=mysite.settings.production

By default we start django site with manage.py and it uses development as default setting:

1
2
3
4
5
6
import os
import sys

if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings") 
    ...

We can change the line os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings") to os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings.dev") for dev settings or os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings.production") for production settings.

From above we can see that django manage.py actually use environment variable DJANGO_SETTINGS_MODULE for specific setting module. We can set this variable before running django:

Unix bash shell:

1
export DJANGO_SETTINGS_MODULE=mysite.settings.dev

or windows shell:

1
set DJANGO_SETTINGS_MODULE=mysite.settings.dev