SlideShare a Scribd company logo
_DJANGO PROJECTS CONFIGURED
FOR MULTIPLE ENVIRONMENTS
KRYSTIAN HANEK
Backend Developer
apptension.com
_DEFAULT DJANGO
CONFIGURATION ISN’T
ENOUGH:
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
_A RECIPE FOR
MULTI-ENVIRONMENT
CONFIGURATION:
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
1. Install virtualenv/virtualenvwrapper
2. Install Django: pip install Django == 1.11.5
3. Create your project: django-admin: django-admin startproject djangohotspot
(djangohotspot) ╭ ~/Workspace/
╰$ tree djangohotspot
djangohotspot
├── djangohotspot
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
└── manage.py
_STARTING YOUR PROJECT
(djangohotspot) ╭ ~/Workspace/
╰$ tree djangohotspot
djangohotspot
├── djangohotspot
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── manage.py
└── requirements
├── base.txt
├── local.txt
├── production.txt
└── test.txt
_CREATING SEPARATE REQUIREMENTS.TXT FILES
_REQUIREMENTS FILES
base.txt
django==1.11.5
# Configuration
django-environ==0.4.4
whitenoise==3.3.0
# Models
django-model-utils==3.0.0
# Images
Pillow==4.2.1
# Password storage
argon2-cffi==16.3.0
# Python-PostgreSQL Database Adapter
psycopg2==2.7.3.1
# Unicode slugification
awesome-slugify==1.6.5
# Time zones support
pytz==2017.2
# Redis support
django-redis==4.8.0
redis>=2.10.5
production.txt
-r base.txt
# WSGI Handler
gevent==1.2.2
gunicorn==19.7.1
# Static and Media Storage
boto3==1.4.7
django-storages==1.6.5
# Email backends for Mailgun, Postmark,
# SendGrid and more
django-anymail==0.11.1
# Raven is the Sentry client
raven==6.1.0
_REQUIREMENTS FILES
test.txt
-r base.txt
coverage==4.4.1
flake8==3.4.1
factory-boy==2.9.2
# pytest
pytest-cov==2.4.0
pytest-django==3.1.2
pytest-factoryboy==1.3.1
pytest-mock==1.6.0
pytest-sugar==0.9.0
local.txt
-r test.txt
-r production.txt
django-extensions==1.9.0
ipdb==0.10.3
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
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
# import from your base settings file
from .base import *
# add toolbar debug
MIDDLEWARE += ['debug_toolbar.middleware.DebugToolbarMiddleware', ]
INSTALLED_APPS += ['debug_toolbar', ]
DEBUG_TOOLBAR_CONFIG = {
'DISABLE_PANELS': [ 'debug_toolbar.panels.redirects.RedirectsPanel', ],
'SHOW_TEMPLATE_CONTEXT': True,
}
# define:
INTERNAL_IPS = ['127.0.0.1']
# add django extension
INSTALLED_APPS += ['django_extensions', ]
_CONFIG.SETTINGS.LOCAL
# security configuration
SECURE_HSTS_SECONDS = 60
SECURE_HSTS_INCLUDE_SUBDOMAINS = env.bool( 'DJANGO_SECURE_HSTS_INCLUDE_SUBDOMAINS', default=True)
SECURE_CONTENT_TYPE_NOSNIFF = env.bool( 'DJANGO_SECURE_CONTENT_TYPE_NOSNIFF', default=True)
SECURE_BROWSER_XSS_FILTER = True
SESSION_COOKIE_SECURE = True
SESSION_COOKIE_HTTPONLY = True
SECURE_SSL_REDIRECT = env.bool('DJANGO_SECURE_SSL_REDIRECT', default=True)
CSRF_COOKIE_SECURE = True
CSRF_COOKIE_HTTPONLY = True
X_FRAME_OPTIONS = 'DENY'
ADMIN_URL = env('DJANGO_ADMIN_URL')
Note: It’s useful to add DJANGO_ADMIN_URL to the production settings. Change it from default to avoid attack attempts on the default
URL admin panel.
_CONFIG.SETTINGS.PRODUCTION 1/3
# Add your domain to:
ALLOWED_HOSTS = env.list('DJANGO_ALLOWED_HOSTS', default=['djangohotspot.pl', ])
# Add Gunicorn:
INSTALLED_APPS += ['gunicorn', ]
# Add django-storage pod AWS:
INSTALLED_APPS += ['storages', ]
AWS_ACCESS_KEY_ID = env('DJANGO_AWS_ACCESS_KEY_ID')
AWS_SECRET_ACCESS_KEY = env('DJANGO_AWS_SECRET_ACCESS_KEY')
AWS_STORAGE_BUCKET_NAME = env('DJANGO_AWS_STORAGE_BUCKET_NAME')
AWS_AUTO_CREATE_BUCKET = True
AWS_QUERYSTRING_AUTH = False
AWS_EXPIRY = 60 * 60 * 24 * 7
MEDIA_URL = 'https://s3.amazonaws.com/%s/' % AWS_STORAGE_BUCKET_NAME
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
_CONFIG.SETTINGS.PRODUCTION 2/3
# Add Sentry
INSTALLED_APPS += ['raven.contrib.django.raven_compat', ]
RAVEN_MIDDLEWARE = ['raven.contrib.django.raven_compat.middleware.SentryResponseErrorIdMiddleware']
MIDDLEWARE = RAVEN_MIDDLEWARE + MIDDLEWARE
SENTRY_DSN = env('DJANGO_SENTRY_DSN')
SENTRY_CLIENT = env('DJANGO_SENTRY_CLIENT', default='raven.contrib.django.raven_compat.DjangoClient')
SENTRY_CELERY_LOGLEVEL = env.int('DJANGO_SENTRY_LOG_LEVEL', logging.INFO )
RAVEN_CONFIG = {
'CELERY_LOGLEVEL': env.int('DJANGO_SENTRY_LOG_LEVEL', logging.INFO ),
'DSN': SENTRY_DSN,
}
# Add Whitenoise
WHITENOISE_MIDDLEWARE = ['whitenoise.middleware.WhiteNoiseMiddleware', ]
MIDDLEWARE = WHITENOISE_MIDDLEWARE + MIDDLEWARE
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
_CONFIG.SETTINGS.PRODUCTION 3/3
# 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
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
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
_THAT’S A WRAP!
VISIT OUR WEBSITE

More Related Content

PDF
Statyczna analiza kodu PHP
The Software House
 
PDF
2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps
Омские ИТ-субботники
 
PDF
Packaging et déploiement d'une application avec Docker et Ansible @DevoxxFR 2015
Stephane Manciot
 
PDF
10 Million hits a day with WordPress using a $15 VPS
Paolo Tonin
 
PDF
Composer Tools & Frameworks for Drupal
Pantheon
 
PDF
Docker remote-api
Eric Ahn
 
PPTX
Real World Lessons on the Pain Points of Node.js Applications
Ben Hall
 
PDF
Into The Box 2018 Going live with commandbox and docker
Ortus Solutions, Corp
 
Statyczna analiza kodu PHP
The Software House
 
2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps
Омские ИТ-субботники
 
Packaging et déploiement d'une application avec Docker et Ansible @DevoxxFR 2015
Stephane Manciot
 
10 Million hits a day with WordPress using a $15 VPS
Paolo Tonin
 
Composer Tools & Frameworks for Drupal
Pantheon
 
Docker remote-api
Eric Ahn
 
Real World Lessons on the Pain Points of Node.js Applications
Ben Hall
 
Into The Box 2018 Going live with commandbox and docker
Ortus Solutions, Corp
 

What's hot (20)

PPTX
Lessons from running potentially malicious code inside containers
Ben Hall
 
PDF
Automating Complex Setups with Puppet
Kris Buytaert
 
PDF
Vagrant for real (codemotion rome 2016)
Michele Orselli
 
PPTX
Running Docker in Development & Production (#ndcoslo 2015)
Ben Hall
 
PDF
Ansible 實戰:top down 觀點
William Yeh
 
PDF
MeaNstack on Docker
Daniel Ku
 
PDF
kubernetes practice
wonyong hwang
 
PPTX
Docker orchestration v4
Hojin Kim
 
PPTX
Running Docker in Development & Production (DevSum 2015)
Ben Hall
 
PDF
Docker composeで開発環境をメンバに配布せよ
Yusuke Kon
 
PDF
App development with quasar (pdf)
wonyong hwang
 
PPTX
Herd your chickens: Ansible for DB2 configuration management
Frederik Engelen
 
PDF
Hands on Docker - Launch your own LEMP or LAMP stack - SunshinePHP
Dana Luther
 
PDF
Dockerを利用したローカル環境から本番環境までの構築設計
Koichi Nagaoka
 
PPTX
Real World Experience of Running Docker in Development and Production
Ben Hall
 
PPT
Running High Performance and Fault Tolerant Elasticsearch Clusters on Docker
Sematext Group, Inc.
 
PDF
Continuous Delivery: The Next Frontier
Carlos Sanchez
 
KEY
Making Your Capistrano Recipe Book
Tim Riley
 
PDF
이미지 기반의 배포 패러다임 Immutable infrastructure
Daegwon Kim
 
PDF
Ninja Build: Simple Guide for Beginners
Chang W. Doh
 
Lessons from running potentially malicious code inside containers
Ben Hall
 
Automating Complex Setups with Puppet
Kris Buytaert
 
Vagrant for real (codemotion rome 2016)
Michele Orselli
 
Running Docker in Development & Production (#ndcoslo 2015)
Ben Hall
 
Ansible 實戰:top down 觀點
William Yeh
 
MeaNstack on Docker
Daniel Ku
 
kubernetes practice
wonyong hwang
 
Docker orchestration v4
Hojin Kim
 
Running Docker in Development & Production (DevSum 2015)
Ben Hall
 
Docker composeで開発環境をメンバに配布せよ
Yusuke Kon
 
App development with quasar (pdf)
wonyong hwang
 
Herd your chickens: Ansible for DB2 configuration management
Frederik Engelen
 
Hands on Docker - Launch your own LEMP or LAMP stack - SunshinePHP
Dana Luther
 
Dockerを利用したローカル環境から本番環境までの構築設計
Koichi Nagaoka
 
Real World Experience of Running Docker in Development and Production
Ben Hall
 
Running High Performance and Fault Tolerant Elasticsearch Clusters on Docker
Sematext Group, Inc.
 
Continuous Delivery: The Next Frontier
Carlos Sanchez
 
Making Your Capistrano Recipe Book
Tim Riley
 
이미지 기반의 배포 패러다임 Immutable infrastructure
Daegwon Kim
 
Ninja Build: Simple Guide for Beginners
Chang W. Doh
 
Ad

Similar to Configuring Django projects for multiple environments (20)

PPTX
7. Project Directory Structure and..pptx
BahubalSingh
 
PDF
Django for mobile applications
Hassan Abid
 
PDF
Django tips & tricks
Renyi Khor
 
PDF
Building a Django App on Heroku
Joe Fusaro
 
PDF
Easy Step-by-Step Guide to Develop REST APIs with Django REST Framework
Inexture Solutions
 
KEY
Django deployment with PaaS
Appsembler
 
PDF
Running Django on Docker: a workflow and code
Danielle Madeley
 
PPTX
Django
Abhijeet Shekhar
 
PDF
Gae Meets Django
fool2nd
 
PDF
Django Overview
Brian Tol
 
PDF
Scalable Django Architecture
Rami Sayar
 
KEY
國民雲端架構 Django + GAE
Winston Chen
 
PDF
GDG Addis - An Introduction to Django and App Engine
Yared Ayalew
 
PDF
Two scoops of Django - Deployment
flywindy
 
PDF
Django 프로젝트 - heroku 배포하기
Jessica Lee
 
PPTX
Journey through high performance django application
bangaloredjangousergroup
 
PPTX
Deploy Your Website with GCP Workshop slides of GDG on Campus UNSTPB
AmaraCostachiu
 
PDF
Django at Scale
bretthoerner
 
KEY
Scaling Django for X Factor - DJUGL Oct 2012
Malcolm Box
 
PPT
Mini Curso Django Ii Congresso Academico Ces
Leonardo Fernandes
 
7. Project Directory Structure and..pptx
BahubalSingh
 
Django for mobile applications
Hassan Abid
 
Django tips & tricks
Renyi Khor
 
Building a Django App on Heroku
Joe Fusaro
 
Easy Step-by-Step Guide to Develop REST APIs with Django REST Framework
Inexture Solutions
 
Django deployment with PaaS
Appsembler
 
Running Django on Docker: a workflow and code
Danielle Madeley
 
Gae Meets Django
fool2nd
 
Django Overview
Brian Tol
 
Scalable Django Architecture
Rami Sayar
 
國民雲端架構 Django + GAE
Winston Chen
 
GDG Addis - An Introduction to Django and App Engine
Yared Ayalew
 
Two scoops of Django - Deployment
flywindy
 
Django 프로젝트 - heroku 배포하기
Jessica Lee
 
Journey through high performance django application
bangaloredjangousergroup
 
Deploy Your Website with GCP Workshop slides of GDG on Campus UNSTPB
AmaraCostachiu
 
Django at Scale
bretthoerner
 
Scaling Django for X Factor - DJUGL Oct 2012
Malcolm Box
 
Mini Curso Django Ii Congresso Academico Ces
Leonardo Fernandes
 
Ad

More from Apptension (7)

PDF
White Space
Apptension
 
PPTX
Team Happiness - O szczęściu w zespole
Apptension
 
PPTX
D3.js - A picture is worth a thousand words
Apptension
 
PDF
Universal Javascript in React
Apptension
 
PDF
Testerzy na orbicie
Apptension
 
PDF
An introduction to Angular2
Apptension
 
PDF
AngularJS - podstawy
Apptension
 
White Space
Apptension
 
Team Happiness - O szczęściu w zespole
Apptension
 
D3.js - A picture is worth a thousand words
Apptension
 
Universal Javascript in React
Apptension
 
Testerzy na orbicie
Apptension
 
An introduction to Angular2
Apptension
 
AngularJS - podstawy
Apptension
 

Recently uploaded (20)

PDF
Advanced LangChain & RAG: Building a Financial AI Assistant with Real-Time Data
Soufiane Sejjari
 
PPTX
Inventory management chapter in automation and robotics.
atisht0104
 
PPTX
IoT_Smart_Agriculture_Presentations.pptx
poojakumari696707
 
PDF
July 2025: Top 10 Read Articles Advanced Information Technology
ijait
 
PPTX
Module2 Data Base Design- ER and NF.pptx
gomathisankariv2
 
PPTX
Chapter_Seven_Construction_Reliability_Elective_III_Msc CM
SubashKumarBhattarai
 
PDF
20ME702-Mechatronics-UNIT-1,UNIT-2,UNIT-3,UNIT-4,UNIT-5, 2025-2026
Mohanumar S
 
PDF
67243-Cooling and Heating & Calculation.pdf
DHAKA POLYTECHNIC
 
PPTX
MSME 4.0 Template idea hackathon pdf to understand
alaudeenaarish
 
PPT
Ppt for engineering students application on field effect
lakshmi.ec
 
PDF
Software Testing Tools - names and explanation
shruti533256
 
DOCX
SAR - EEEfdfdsdasdsdasdasdasdasdasdasdasda.docx
Kanimozhi676285
 
PDF
Natural_Language_processing_Unit_I_notes.pdf
sanguleumeshit
 
PDF
Zero carbon Building Design Guidelines V4
BassemOsman1
 
PDF
dse_final_merit_2025_26 gtgfffffcjjjuuyy
rushabhjain127
 
PPTX
22PCOAM21 Session 1 Data Management.pptx
Guru Nanak Technical Institutions
 
PDF
Cryptography and Information :Security Fundamentals
Dr. Madhuri Jawale
 
PPTX
Tunnel Ventilation System in Kanpur Metro
220105053
 
PDF
Top 10 read articles In Managing Information Technology.pdf
IJMIT JOURNAL
 
PDF
JUAL EFIX C5 IMU GNSS GEODETIC PERFECT BASE OR ROVER
Budi Minds
 
Advanced LangChain & RAG: Building a Financial AI Assistant with Real-Time Data
Soufiane Sejjari
 
Inventory management chapter in automation and robotics.
atisht0104
 
IoT_Smart_Agriculture_Presentations.pptx
poojakumari696707
 
July 2025: Top 10 Read Articles Advanced Information Technology
ijait
 
Module2 Data Base Design- ER and NF.pptx
gomathisankariv2
 
Chapter_Seven_Construction_Reliability_Elective_III_Msc CM
SubashKumarBhattarai
 
20ME702-Mechatronics-UNIT-1,UNIT-2,UNIT-3,UNIT-4,UNIT-5, 2025-2026
Mohanumar S
 
67243-Cooling and Heating & Calculation.pdf
DHAKA POLYTECHNIC
 
MSME 4.0 Template idea hackathon pdf to understand
alaudeenaarish
 
Ppt for engineering students application on field effect
lakshmi.ec
 
Software Testing Tools - names and explanation
shruti533256
 
SAR - EEEfdfdsdasdsdasdasdasdasdasdasdasda.docx
Kanimozhi676285
 
Natural_Language_processing_Unit_I_notes.pdf
sanguleumeshit
 
Zero carbon Building Design Guidelines V4
BassemOsman1
 
dse_final_merit_2025_26 gtgfffffcjjjuuyy
rushabhjain127
 
22PCOAM21 Session 1 Data Management.pptx
Guru Nanak Technical Institutions
 
Cryptography and Information :Security Fundamentals
Dr. Madhuri Jawale
 
Tunnel Ventilation System in Kanpur Metro
220105053
 
Top 10 read articles In Managing Information Technology.pdf
IJMIT JOURNAL
 
JUAL EFIX C5 IMU GNSS GEODETIC PERFECT BASE OR ROVER
Budi Minds
 

Configuring Django projects for multiple environments

  • 1. _DJANGO PROJECTS CONFIGURED FOR MULTIPLE ENVIRONMENTS KRYSTIAN HANEK Backend Developer apptension.com
  • 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
  • 6. 1. Install virtualenv/virtualenvwrapper 2. Install Django: pip install Django == 1.11.5 3. Create your project: django-admin: django-admin startproject djangohotspot (djangohotspot) ╭ ~/Workspace/ ╰$ tree djangohotspot djangohotspot ├── djangohotspot │ ├── __init__.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py └── manage.py _STARTING YOUR PROJECT
  • 7. (djangohotspot) ╭ ~/Workspace/ ╰$ tree djangohotspot djangohotspot ├── djangohotspot │ ├── __init__.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── manage.py └── requirements ├── base.txt ├── local.txt ├── production.txt └── test.txt _CREATING SEPARATE REQUIREMENTS.TXT FILES
  • 8. _REQUIREMENTS FILES base.txt django==1.11.5 # Configuration django-environ==0.4.4 whitenoise==3.3.0 # Models django-model-utils==3.0.0 # Images Pillow==4.2.1 # Password storage argon2-cffi==16.3.0 # Python-PostgreSQL Database Adapter psycopg2==2.7.3.1 # Unicode slugification awesome-slugify==1.6.5 # Time zones support pytz==2017.2 # Redis support django-redis==4.8.0 redis>=2.10.5 production.txt -r base.txt # WSGI Handler gevent==1.2.2 gunicorn==19.7.1 # Static and Media Storage boto3==1.4.7 django-storages==1.6.5 # Email backends for Mailgun, Postmark, # SendGrid and more django-anymail==0.11.1 # Raven is the Sentry client raven==6.1.0
  • 9. _REQUIREMENTS FILES test.txt -r base.txt coverage==4.4.1 flake8==3.4.1 factory-boy==2.9.2 # pytest pytest-cov==2.4.0 pytest-django==3.1.2 pytest-factoryboy==1.3.1 pytest-mock==1.6.0 pytest-sugar==0.9.0 local.txt -r test.txt -r production.txt django-extensions==1.9.0 ipdb==0.10.3
  • 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
  • 12. # import from your base settings file from .base import * # add toolbar debug MIDDLEWARE += ['debug_toolbar.middleware.DebugToolbarMiddleware', ] INSTALLED_APPS += ['debug_toolbar', ] DEBUG_TOOLBAR_CONFIG = { 'DISABLE_PANELS': [ 'debug_toolbar.panels.redirects.RedirectsPanel', ], 'SHOW_TEMPLATE_CONTEXT': True, } # define: INTERNAL_IPS = ['127.0.0.1'] # add django extension INSTALLED_APPS += ['django_extensions', ] _CONFIG.SETTINGS.LOCAL
  • 13. # security configuration SECURE_HSTS_SECONDS = 60 SECURE_HSTS_INCLUDE_SUBDOMAINS = env.bool( 'DJANGO_SECURE_HSTS_INCLUDE_SUBDOMAINS', default=True) SECURE_CONTENT_TYPE_NOSNIFF = env.bool( 'DJANGO_SECURE_CONTENT_TYPE_NOSNIFF', default=True) SECURE_BROWSER_XSS_FILTER = True SESSION_COOKIE_SECURE = True SESSION_COOKIE_HTTPONLY = True SECURE_SSL_REDIRECT = env.bool('DJANGO_SECURE_SSL_REDIRECT', default=True) CSRF_COOKIE_SECURE = True CSRF_COOKIE_HTTPONLY = True X_FRAME_OPTIONS = 'DENY' ADMIN_URL = env('DJANGO_ADMIN_URL') Note: It’s useful to add DJANGO_ADMIN_URL to the production settings. Change it from default to avoid attack attempts on the default URL admin panel. _CONFIG.SETTINGS.PRODUCTION 1/3
  • 14. # Add your domain to: ALLOWED_HOSTS = env.list('DJANGO_ALLOWED_HOSTS', default=['djangohotspot.pl', ]) # Add Gunicorn: INSTALLED_APPS += ['gunicorn', ] # Add django-storage pod AWS: INSTALLED_APPS += ['storages', ] AWS_ACCESS_KEY_ID = env('DJANGO_AWS_ACCESS_KEY_ID') AWS_SECRET_ACCESS_KEY = env('DJANGO_AWS_SECRET_ACCESS_KEY') AWS_STORAGE_BUCKET_NAME = env('DJANGO_AWS_STORAGE_BUCKET_NAME') AWS_AUTO_CREATE_BUCKET = True AWS_QUERYSTRING_AUTH = False AWS_EXPIRY = 60 * 60 * 24 * 7 MEDIA_URL = 'https://s3.amazonaws.com/%s/' % AWS_STORAGE_BUCKET_NAME DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage' _CONFIG.SETTINGS.PRODUCTION 2/3
  • 15. # Add Sentry INSTALLED_APPS += ['raven.contrib.django.raven_compat', ] RAVEN_MIDDLEWARE = ['raven.contrib.django.raven_compat.middleware.SentryResponseErrorIdMiddleware'] MIDDLEWARE = RAVEN_MIDDLEWARE + MIDDLEWARE SENTRY_DSN = env('DJANGO_SENTRY_DSN') SENTRY_CLIENT = env('DJANGO_SENTRY_CLIENT', default='raven.contrib.django.raven_compat.DjangoClient') SENTRY_CELERY_LOGLEVEL = env.int('DJANGO_SENTRY_LOG_LEVEL', logging.INFO ) RAVEN_CONFIG = { 'CELERY_LOGLEVEL': env.int('DJANGO_SENTRY_LOG_LEVEL', logging.INFO ), 'DSN': SENTRY_DSN, } # Add Whitenoise WHITENOISE_MIDDLEWARE = ['whitenoise.middleware.WhiteNoiseMiddleware', ] MIDDLEWARE = WHITENOISE_MIDDLEWARE + MIDDLEWARE STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage' _CONFIG.SETTINGS.PRODUCTION 3/3
  • 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
  • 19. _THAT’S A WRAP! VISIT OUR WEBSITE