A Django site has a few components:
- the core software and 3rd party modules (installed with pip into a virtualenv)
- settings.py (identified by the DJANGO_SETTINGS_MODULE environment variable) known as "the settings file"
- manage.py (which basically takes over from django-admin once your site is created)
- urls.py (referenced by settings file)
- the apps you create and 3rd party apps
- static content to support the site
Optionally your site may also have:
- files uploaded to the site which need to be served from the site
The typical site directory looks like this:
my_site
my_site/__init__.py
my_site/settings.py
my_site/manage.py
my_site/urls.py
The settings file (settings.py) is pretty much a custom file per site that uses a bunch of Django applications (even if there's really only the one core application you're deploying there you inevitably end up using a bunch of Django core applications alongside it like authentication and admin.)
Fortunately the static content and uploaded file content are managed by the settings file parameters STATIC_ROOT (and STATIC_URL) and MEDIA_ROOT (and MEDIA_URL). For more information about dealing with static files see the official static files HOWTO.
Generally speaking the settings file should be version-controlled, but if it's stored in a public repository then there'll be content that should never be checked in. This includes such things as the database credentials, the SECRET_KEY and possibly other values (like SENTRY_DSN, etc.)
Three approaches are possible, depending on the expected variations of the settings file (that is, how often you expect it to change over the lifespan of a deployment):
- The easiest, but least flexible approach is to mock up the settings file with dummy values and when deploying make a copy of the file for production and edit the appropriate values into that copy.
- If the file only has a couple of values that you wish to remove from the repository then you can have them stored in separate files. This approach would typically be used where you only have one deployment of the application, or where all the deployments are identical. The secret valies are then read in by the settings file like so:
SECRET_KEY = open('/home/user/secret-key.txt', 'r').read().strip()
The third option, for use when you have several such values and varying deployments, is to store them in a separate Python file and invoke that file from your settings file. At the very end of your settings file, add:
# now load local modifications to these settings import os with open(os.environ['DJANGO_LOCAL_SETTINGS']) as f: exec f
Then you set the environment variable DJANGO_LOCAL_SETTINGS to point to a Python source file which contains the customisations of the repository settings file, for example:
DEBUG = True
TEMPLATE_DEBUG = DEBUG
ADMINS.append(('Richard Jones', 'richard@host.example'))
DATABASES['default'] = dict(
ENGINE = 'django.db.backends.postgresql_psycopg2',
NAME = 'pyweek',
USER = 'richard',
PASSWORD = 'jfruj3hsie',
)
STATIC_ROOT = '/path/to/static/media'
MEDIA_ROOT = '/path/to/uploaded/media'
SECRET_KEY = '7$LQcfFv_KB}+RXH,)do&jYF.S$WLZv^u+)5qbzT>HphM1uc'
SENTRY_DSN = 'https://cf8bcc5a9a0e617fcba15d5c5e08383f:297c61c2b58a68b837cf2adb12bc1a20@app.getsentry.com/757'
This allows you to mess with settings without affecting the checked-out settings file.
Need to add something about manage.py and urls.py and making the site directory a Python package.