3. The default Django configuration lacks:
Multiple settings files for different environments.
Separate packages for different environments.
Flexible configuration without having to alter the code.
Solutions dedicated for production environment: admin panel path, error logging (e.g.
Sentry), cache configuration (memcache/redis), storing files uploaded to the cloud by the
users (S3), HSTS, secure cookies.
Solutions dedicated for testing environment: disabling template debugging, in-memory
caching, sending emails to the console, password hasher, storing the templates.
_DJANGO PROJECTS CONFIGURED FOR MULTIPLE ENVIRONMENTS
5. Let’s configure a Django project for multiple
environments (production, local and testing).
Our app will use several third-party tools including
PostgreSQL, Sentry, AWS, WhiteNoise, Gunicorn,
Redis, Anymail.
_A RECIPE FOR MULTI-ENVIRONMENT CONFIGURATION
10. Let’s not store settings.py in the catalog of your
project’s main app:
djangohotspot/djangohotspot/settings.p
y
Create a python module (in the main catalog) called
config, and an additional settings module
within it.
_SEPARATING THE SETTINGS (djangohotspot) ╭ ~/Workspace/Prezentacja
╰$ tree djangohotspot
djangohotspot
├── config
│ ├── __init__.py
│ └── settings
│ ├── base.py
│ ├── __init__.py
│ ├── local.py
│ ├── production.py
│ └── test.py
├── djangohotspot
│ ├── __init__.py
│ ├── urls.py
│ └── wsgi.py
├── manage.py
└── requirements
├── base.txt
├── local.txt
├── production.txt
└── test.txt
11. ROOT_DIR = environ.Path (__file__) - 3 # djangohotspot/
APPS_DIR = ROOT_DIR.path ('djangohotspot') # path for django apps
INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + LOCAL_APPS
AUTOSLUG_SLUGIFY_FUNCTION = 'slugify.slugify' # allows you to define a function for
unicode-supported Slug
DATABASES = { 'default': env.db('DATABASE_URL', default='postgres:///djangohotspot'), }
DATABASES['default']['ATOMIC_REQUESTS'] = True # allows you to open and commit
transaction when there are no exceptions. This could affect the performance negatively
for traffic-heavy apps.
EMAIL_BACKEND = env('DJANGO_EMAIL_BACKEND',
default='django.core.mail.backends.smtp.EmailBackend')
ADMIN_URL = env('DJANGO_ADMIN_URL', default=r'^admin/')
PASSWORD_HASHERS = ['django.contrib.auth.hashers.Argon2PasswordHasher', (...)] # add this
object at the beginning of the list
_CONFIG.SETTINGS.BASE
16. # Disable debugging
DEBUG = False
TEMPLATES[0]['OPTIONS']['debug'] = False
# Sent emails are stored in the memory and available at django.core.mail.outbox
EMAIL_BACKEND = 'django.core.mail.backends.locmem.EmailBackend'
# Set cache
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
'LOCATION': ''
}
}
# Set password hasher to speed up the testing
PASSWORD_HASHERS = ['django.contrib.auth.hashers.MD5PasswordHasher', ]
# Djanglo templates can be stored in the memory
TEMPLATES[0]['OPTIONS']['loaders'] = [
['django.template.loaders.cached.Loader', [
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader', ]
, ]
, ]
_CONFIG.SETTINGS.TEST
17. 1. Move uwsgi.py and urls.py in djangohotspot/djangohotspot to the config module.
2. In config.settings add the following edits:
WSGI_APPLICATION = 'config.wsgi.application'
ROOT_URLCONF = 'config.urls'
3. Add the following code to config.urls in order to debug 4xx and 5xx pages:
if settings.DEBUG:
urlpatterns += [
url(r'^400/$', default_views.bad_request, kwargs={'exception': Exception('Bad Request!')}),
url(r'^403/$', default_views.permission_denied,kwargs={'exception': Exception('Permission Denied')}),
url(r'^404/$', default_views.page_not_found,kwargs={'exception': Exception('Page not Found')}),
url(r'^500/$', default_views.server_error),
]
if 'debug_toolbar' in settings.INSTALLED_APPS:
import debug_toolbar
urlpatterns = [
url(r'^__debug__/', include(debug_toolbar.urls)),
] + urlpatterns
_UWSGI.PY & URLS.PY
18. import os
import sys
from django.core.wsgi import get_wsgi_application
app_path = os.path.dirname (os.path.abspath (__file__)).replace('/config', '')
sys.path.append (os.path.join (app_path, 'djangohotspot'))
if os.environ.get ('DJANGO_SETTINGS_MODULE') == 'config.settings.production':
from raven.contrib.django.raven_compat.middleware.wsgi import Sentry
os.environ.setdefault ('DJANGO_SETTINGS_MODULE', 'config.settings.production')
application = get_wsgi_application ()
if os.environ.get ('DJANGO_SETTINGS_MODULE') == 'config.settings.production':
application = Sentry(application )
_CONFIG.UWSGI