Privacy Policy
Snippets index

  Flexible settings in Django

The proposed arrangement is adapted from Two Scoops of Django, but with these additional advantages:

  • the Django "default" just work, both in development and production: no DJANGO_SETTINGS_MODULE env variable nor --settings option are required
  • a convenient debug.py file is provided for occasional DEBUG mode activation in production

(1) create a "settings" module under main project

PROJECT/
├── __init__.py
├── settings
│   ├── __init__.py
│   ├── local.py
│   └── settings.py

__init__.py includes local.py, which in turn will include settings.py

from PROJECT.settings.local import *

(2) settings/settings.py contains all defaults shared both in development and production

Secret key and db details are left off

...
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = ''

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = False
ALLOWED_HOSTS = '*'

# Database
DATABASES = {
   'default': {
       'ENGINE': 'django.db.backends.postgresql_psycopg2',
       'HOST': 'localhost',
       'NAME': '',
       'USER': '',
       'PASSWORD': '',
   }
}

(3) settings/local.py provides local overrides:

Requirements:

  • starts including all settings
  • provides the secret key and db details
  • more overrides may follow
from PROJECT.settings.settings import *

SECRET_KEY = '... my very secret key ...'

# Database
DATABASES = {
   'default': {
       'ENGINE': 'django.db.backends.postgresql_psycopg2',
       'HOST': 'real host',
       'NAME': 'real db name',
       'USER': 'real db user',
       'PASSWORD': 'real db password',
   }
}

...

Note that local.py is not kept in the repo, and must be created manually.

A "local.py.sample" sample file is provided.

(4) "debug.py" is provided to add DEBUG=TRUE setting, and can be used as follows:

python manage.py runserver 0.0.0.0:8000 --settings=PROJECT.settings.debug

debug.py:

from PROJECT.settings.local import *

DEBUG = True
ALLOWED_HOSTS = ['*', ]

#
# Verbose db logging ...
#

# LOGGING = {
#     'version': 1,
#     'disable_existing_loggers': False,
#     'formatters': {
#         'verbose': {
#             'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s'
#         },
#         'simple': {
#             'format': '%(levelname)s %(message)s'
#         },
#     },
#     'handlers': {
#         'console': {
#             'level': 'DEBUG',
#             'class': 'logging.StreamHandler',
#             'formatter': 'simple'
#         },
#     },
#     'loggers': {
#         'django.db.backends': {
#             'handlers': ['console', ],
#             'level': 'DEBUG',
#         },
#     },
# }

(5) more setting layouts can be kept in the module for versioning

PROJECT/
├── __init__.py
├── settings
│   ├── __init__.py
│   ├── local.py
│   ├── settings.py
│   ├── development.py
│   ├── development_postgresql.py
│   ├── development_sqlite.py
│   ├── dualdb.py
│   ├── production.py
│   ├── production_postgresql.py
│   ├── production_unix.py
│   ├── smtp_local_settings.py
│   ├── test_settings.py
│   └── test_no_migrations.py

and eventually referred in "local.py" as follows:

from PROJECT.settings.development_postgresql import *

(6) WSGI config

Just use default settings:

import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "PROJECT.settings")
application = get_wsgi_application()