David Seddon
david@seddonym.me
http://seddonym.me
Benevolent Dictator for Life, Django
"Do the simplest thing that
could possibly work"
settings
- __init__.py
- base.py
- local.py
- staging.py
- production.py
# base.py
INSTALLED_APPS = [
'myapp',
]
# local.py
from .base import *
INSTALLED_APPS += [
'debug_toolbar'
]
The One True Way
ALLOWED_HOSTS = ['mysite.com']
BASE_URL = 'http://mysite.com'
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'mysite',
'USER': 'mysite',
'PASSWORD': '',
}
}
LOGGING = {
'version': 1,
'disable_existing_loggers': True,
'formatters': {
'simple': {
'format': '%(levelname)s %(message)s'
},
},
'handlers': {
'null': {
'level': 'DEBUG',
'class': 'logging.NullHandler',
},
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
'formatter': 'simple'
},
'mail_admins': {
'level': 'ERROR',
'class': 'django.utils.log.AdminEmailHandler',
}
},
'loggers': {
'django': {
'handlers': ['null'],
'propagate': True,
'level': 'INFO',
},
'django.request': {
'handlers': ['mail_admins'],
'level': 'ERROR',
'propagate': False,
},
'mysite.custom': {
'handlers': ['console', 'mail_admins'],
'level': 'INFO',
}
}
}
# local.py
from .base import *
SITENAME = 'mysite'
# What do we do here?
from .secret import *
https://github.com/seddonym/bobsleigh
myproject
__init__.py
manage.py
wsgi.py
settings
__init__.py
project.py
installations.py
secret.py
# manage.py
#!/usr/bin/env python
if __name__ == "__main__":
from bobsleigh.runner import manage_environment
manage_environment()
# wsgi.py
from bobsleigh.runner import wsgi_environment
application = wsgi_environment()
The basic settings for the project.
from django.conf.global_settings import *
INSTALLED_APPS += [
'myapp',
]
Sensitive settings not under version control.
# secret.py
SECRET_KEY = 'w&P%jcQM&cz5%Nmdkn$wyKI8Mx8G3ZZ!S^kUX^5mKSom7t5pqLKtLGV!EOn$Y7^K6ih470Hz'
DB_PASS = 'mypassword'
Describes how settings should be managed for each installation. Class based settings!
from bobsleigh.handlers import InstallationHandler
INSTALLATIONS = [
# Local installation
InstallationHandler(domain='mysite.localhost',
host='localhost'),
# Dev installation
InstallationHandler(domain='dev.mysite.com',
host='mydevserver'),
# Live installation
InstallationHandler(domain='mysite.com',
host='myliveserver'),
]
# Local installation
InstallationHandler(domain='mysite.localhost',
host='localhost')
Simplistic example
InstallationHandler(
domain='mysite.localhost',
host='localhost',
debug=True,
monitor=True
virtualenv_path='/opt/.virtualenvs/mysite',
log_path='/var/log/mysite',
project_path='/opt/www/mysite',
static_path='/opt/var/www/mysite/static',
media_path='/opt/var/www/mysite/media',
db_name='mysite',
db_user='mysite',
python='python3.0',
server_email='Mysite <contact@mysite.localhost>',
email_host_user='mysite',
email_host='smtp.mailserver.com',
extra_settings={
'CELERY_ALWAYS_EAGER': True,
}
)
Real world example
class LocalHandler(InstallationHandler):
"For my local development setup."
# Has an config object self.config, with various attributes
def get_required_kwargs(self):
# Returns required kwargs, which will be set on self.config
def get_optional_kwargs(self):
# Returns optional kwargs, with defaults, to be set on self.config
def get_config_patterns(self):
# Specifies how to set self.config attributes based on the values
# of other self.config attributes
def adjust(self):
# Uses the self.config attributes to build the settings object
# that will eventually be available as django.conf.settings
class LocalHandler(InstallationHandler):
"For my local development setup."
def get_required_kwargs(self):
return ('sitename',)
def get_optional_kwargs(self):
optional_kwargs = super(LocalHandler, self).get_optional_kwargs()
optional_kwargs.update({
'host': 'lanky',
'debug': True,
'monitor': True,
'email_host': 'smtp.gmail.com',
'email_use_tls': True,
'email_port': 587,
'email_host_user': 'davidseddonis@gmail.com',
'protocol': 'http',
})
return optional_kwargs
def get_config_patterns(self):
patterns = super(LocalHandler, self).get_config_patterns()
patterns += (
('domain', '%(sitename)s.localhost'),
('base_url', '%(protocol)s://%(domain)s'),
('db_name', '%(sitename)s'),
('db_user', '%(sitename)s'),
('log_path', '/var/log/django/%(sitename)s'),
('static_path', '/opt/var/www/%(sitename)s/static'),
('media_path', '/opt/var/www/%(sitename)s/uploads'),
('virtualenv_path', '/opt/.virtualenvs/%(sitename)s'),
('project_path', '/opt/www/%(sitename)s'),
('server_email', 'contact@%(domain)s'),
)
return patterns
def adjust(self):
super(LocalHandler, self).adjust()
self._settings['EMAIL_USE_TLS'] = self.config.email_use_tls
self._settings['EMAIL_PORT'] = self.config.email_port
self._settings['BASE_URL'] = self.config.base_url
INSTALLATIONS = [
LocalHandler('mysite'),
]
https://github.com/seddonym/bobsleigh-seddonym/
# project.py
from bobsleigh_seddonym.settings.base import *
INSTALLED_APPS += [
'myapp',
]
# installations.py
from bobsleigh_seddonym.handlers.local import LocalHandler
from bobsleigh_seddonym.handlers.webfaction import DevHandler, LiveHandler
INSTALLATIONS = [
LocalHandler(sitename='mysite'),
DevHandler(sitename='dev',
host='web123.webfaction.com',
webfaction_user='myuser',
domain='dev.mysite.com',
server_email='Mysite <contact@dev.mysite.com>',
prefixed_name='mysite_dev'),
LiveHandler(sitename='live',
host='web123.webfaction.com',
webfaction_user='myuser',
domain='mysite.com',
server_email='Mysite <contact@mysite.com>',
prefixed_name='mysite_live'),
]
seddonym.me
github.com/seddonym
david@seddonym.me
I don't really tweet