mirror of
https://github.com/Southampton-RSG/breccia-mapper.git
synced 2026-03-03 11:27:09 +00:00
Upgrade versions of most packages and make other required changes to ensure compatibility. Update database models and migrations to match new requirements set by Django
460 lines
12 KiB
Python
460 lines
12 KiB
Python
"""
|
|
Django settings for breccia_mapper project.
|
|
|
|
Generated by 'django-admin startproject' using Django 2.2.9.
|
|
|
|
For more information on this file, see
|
|
https://docs.djangoproject.com/en/2.2/topics/settings/
|
|
|
|
For the full list of settings and their values, see
|
|
https://docs.djangoproject.com/en/2.2/ref/settings/
|
|
|
|
Before production deployment, see
|
|
https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/
|
|
|
|
|
|
Many configuration settings are input from `settings.ini`.
|
|
The most likely required settings are: SECRET_KEY, DEBUG, ALLOWED_HOSTS, DATABASE_URL, PROJECT_*_NAME, EMAIL_*
|
|
|
|
- PARENT_PROJECT_NAME
|
|
default: Parent Project Name
|
|
Displayed in templates where the name of the parent project should be used
|
|
|
|
- PROJECT_LONG_NAME
|
|
default: Project Long Name
|
|
Displayed in templates where the full name of the project should be used
|
|
|
|
- PROJECT_SHORT_NAME
|
|
default: shortname
|
|
Displayed in templates where a short identifier for the project should be used
|
|
|
|
- SECRET_KEY (REQUIRED)
|
|
Used to generate CSRF tokens - must never be made public
|
|
|
|
- DEBUG
|
|
default: False
|
|
Should the server run in debug mode? Provides information to users which is unsafe in production
|
|
|
|
- ALLOWED_HOSTS
|
|
default: * if DEBUG else localhost
|
|
Accepted values for server header in request - protects against CSRF and CSS attacks
|
|
|
|
- DATABASE_URL
|
|
default: sqlite://db.sqlite3
|
|
URL to database - uses format described at https://github.com/jacobian/dj-database-url
|
|
|
|
- DBBACKUP_STORAGE_LOCATION
|
|
default: .dbbackup
|
|
Directory where database backups should be stored
|
|
|
|
- LANGUAGE_CODE
|
|
default: en-gb
|
|
Default language - used for translation - has not been enabled
|
|
|
|
- TIME_ZONE
|
|
default: UTC
|
|
Default timezone
|
|
|
|
- LOG_LEVEL
|
|
default: INFO
|
|
Level of messages written to log file
|
|
|
|
- LOG_FILENAME
|
|
default: debug.log
|
|
Path to logfile
|
|
|
|
- LOG_DAYS
|
|
default: 14
|
|
Number of days of logs to keep - logfile is rotated out at the end of each day
|
|
|
|
- EMAIL_HOST
|
|
default: None
|
|
Hostname of SMTP server
|
|
|
|
- DEFAULT_FROM_EMAIL
|
|
default: None
|
|
Email address from which messages are sent
|
|
|
|
- EMAIL_FILE_PATH (debug only)
|
|
default: mail.log
|
|
Directory where emails will be stored if not using an SMTP server
|
|
|
|
- EMAIL_HOST_USER
|
|
default: None
|
|
Username to authenticate with SMTP server
|
|
|
|
- EMAIL_HOST_PASSWORD
|
|
default: None
|
|
Password to authenticate with SMTP server
|
|
|
|
- EMAIL_PORT
|
|
default: 25
|
|
Port to access on SMTP server
|
|
|
|
- EMAIL_USE_TLS
|
|
default: True if EMAIL_PORT == 587 else False
|
|
Use TLS to communicate with SMTP server? Usually on port 587
|
|
|
|
- EMAIL_USE_SSL
|
|
default: True if EMAIL_PORT == 465 else False
|
|
Use SSL to communicate with SMTP server? Usually on port 465
|
|
|
|
- GOOGLE_MAPS_API_KEY
|
|
default: None
|
|
Google Maps API key to display maps of people's locations
|
|
"""
|
|
|
|
import logging
|
|
import logging.config
|
|
import pathlib
|
|
|
|
from django.urls import reverse_lazy
|
|
|
|
from decouple import config, Csv
|
|
import dj_database_url
|
|
|
|
# Settings exported to templates
|
|
# https://github.com/jakubroztocil/django-settings-export
|
|
|
|
SETTINGS_EXPORT = [
|
|
'DEBUG',
|
|
'PARENT_PROJECT_NAME',
|
|
'PROJECT_LONG_NAME',
|
|
'PROJECT_SHORT_NAME',
|
|
'GOOGLE_MAPS_API_KEY',
|
|
]
|
|
|
|
PARENT_PROJECT_NAME = config('PARENT_PROJECT_NAME',
|
|
default='Parent Project Name')
|
|
PROJECT_LONG_NAME = config('PROJECT_LONG_NAME', default='Project Long Name')
|
|
PROJECT_SHORT_NAME = config('PROJECT_SHORT_NAME', default='shortname')
|
|
|
|
# Build paths inside the project like this: BASE_DIR.joinpath(...)
|
|
BASE_DIR = pathlib.Path(__file__).parent.parent
|
|
|
|
# SECURITY WARNING: keep the secret key used in production secret!
|
|
SECRET_KEY = config('SECRET_KEY')
|
|
|
|
# SECURITY WARNING: don't run with debug turned on in production!
|
|
DEBUG = config('DEBUG', default=False, cast=bool)
|
|
|
|
ALLOWED_HOSTS = config(
|
|
'ALLOWED_HOSTS',
|
|
default='*' if DEBUG else '127.0.0.1,localhost,localhost.localdomain',
|
|
cast=Csv())
|
|
|
|
# Application definition
|
|
|
|
DJANGO_APPS = [
|
|
'django.contrib.admin',
|
|
'django.contrib.auth',
|
|
'django.contrib.contenttypes',
|
|
'django.contrib.sessions',
|
|
'django.contrib.messages',
|
|
'django.contrib.staticfiles',
|
|
]
|
|
|
|
THIRD_PARTY_APPS = [
|
|
'bootstrap4',
|
|
'constance',
|
|
'constance.backends.database',
|
|
'dbbackup',
|
|
'django_countries',
|
|
'django_select2',
|
|
'rest_framework',
|
|
'post_office',
|
|
'bootstrap_datepicker_plus',
|
|
'hijack',
|
|
]
|
|
|
|
FIRST_PARTY_APPS = [
|
|
'people',
|
|
'activities',
|
|
'export',
|
|
]
|
|
|
|
INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + FIRST_PARTY_APPS
|
|
|
|
MIDDLEWARE = [
|
|
'django.middleware.security.SecurityMiddleware',
|
|
'django.contrib.sessions.middleware.SessionMiddleware',
|
|
'django.middleware.common.CommonMiddleware',
|
|
'django.middleware.csrf.CsrfViewMiddleware',
|
|
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
|
'django.contrib.messages.middleware.MessageMiddleware',
|
|
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
|
'hijack.middleware.HijackUserMiddleware',
|
|
]
|
|
|
|
ROOT_URLCONF = 'breccia_mapper.urls'
|
|
|
|
TEMPLATES = [
|
|
{
|
|
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
|
'DIRS': [BASE_DIR.joinpath('breccia_mapper', 'templates')],
|
|
'APP_DIRS': True,
|
|
'OPTIONS': {
|
|
'context_processors': [
|
|
'django_settings_export.settings_export',
|
|
'constance.context_processors.config',
|
|
'django.template.context_processors.debug',
|
|
'django.template.context_processors.request',
|
|
'django.contrib.auth.context_processors.auth',
|
|
'django.contrib.messages.context_processors.messages',
|
|
],
|
|
},
|
|
},
|
|
]
|
|
|
|
WSGI_APPLICATION = 'breccia_mapper.wsgi.application'
|
|
|
|
# Database
|
|
# https://docs.djangoproject.com/en/2.2/ref/settings/#databases
|
|
|
|
DATABASES = {
|
|
'default':
|
|
config('DATABASE_URL',
|
|
default='sqlite:///' + str(BASE_DIR.joinpath('db.sqlite3')),
|
|
cast=dj_database_url.parse)
|
|
}
|
|
|
|
# Django DBBackup
|
|
# https://django-dbbackup.readthedocs.io/en/stable/index.html
|
|
|
|
DBBACKUP_STORAGE = 'django.core.files.storage.FileSystemStorage'
|
|
DBBACKUP_STORAGE_OPTIONS = {
|
|
'location':
|
|
config('DBBACKUP_STORAGE_LOCATION',
|
|
default=BASE_DIR.joinpath('.dbbackup')),
|
|
}
|
|
|
|
# Django REST Framework
|
|
# https://www.django-rest-framework.org/
|
|
|
|
REST_FRAMEWORK = {
|
|
'DEFAULT_PERMISSION_CLASSES': [
|
|
'rest_framework.permissions.IsAuthenticated',
|
|
],
|
|
'DEFAULT_RENDERER_CLASSES': [
|
|
'rest_framework.renderers.JSONRenderer',
|
|
'rest_framework_csv.renderers.CSVRenderer',
|
|
'rest_framework.renderers.BrowsableAPIRenderer',
|
|
],
|
|
}
|
|
|
|
# Password validation
|
|
# https://docs.djangoproject.com/en/2.2/ref/settings/#auth-password-validators
|
|
|
|
AUTH_PASSWORD_VALIDATORS = [
|
|
{
|
|
'NAME':
|
|
'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
|
|
},
|
|
{
|
|
'NAME':
|
|
'django.contrib.auth.password_validation.MinimumLengthValidator',
|
|
},
|
|
{
|
|
'NAME':
|
|
'django.contrib.auth.password_validation.CommonPasswordValidator',
|
|
},
|
|
{
|
|
'NAME':
|
|
'django.contrib.auth.password_validation.NumericPasswordValidator',
|
|
},
|
|
]
|
|
|
|
# Custom user model
|
|
# https://docs.djangoproject.com/en/2.2/topics/auth/customizing/#using-a-custom-user-model-when-starting-a-project
|
|
|
|
AUTH_USER_MODEL = 'people.User'
|
|
|
|
# Login flow
|
|
|
|
LOGIN_URL = reverse_lazy('login')
|
|
|
|
LOGIN_REDIRECT_URL = reverse_lazy('people:person.profile')
|
|
|
|
# Internationalization
|
|
# https://docs.djangoproject.com/en/2.2/topics/i18n/
|
|
|
|
LANGUAGE_CODE = config('LANGUAGE_CODE', default='en-gb')
|
|
|
|
TIME_ZONE = config('TIME_ZONE', default='UTC')
|
|
|
|
USE_I18N = True
|
|
|
|
USE_L10N = True
|
|
|
|
USE_TZ = True
|
|
|
|
# Static files (CSS, JavaScript, Images)
|
|
# https://docs.djangoproject.com/en/2.2/howto/static-files/
|
|
|
|
STATIC_URL = '/static/'
|
|
|
|
STATIC_ROOT = BASE_DIR.joinpath('static')
|
|
|
|
STATICFILES_DIRS = [BASE_DIR.joinpath('breccia_mapper', 'static')]
|
|
|
|
# Logging - NB the logger name is empty to capture all output
|
|
|
|
LOGGING = {
|
|
'version': 1,
|
|
'disable_existing_loggers': False,
|
|
'handlers': {
|
|
'file': {
|
|
'level': config('LOG_LEVEL', default='INFO'),
|
|
'class': 'logging.handlers.TimedRotatingFileHandler',
|
|
'filename': config('LOG_FILENAME', default='debug.log'),
|
|
'when': 'midnight',
|
|
'backupCount': config('LOG_DAYS', default=14, cast=int),
|
|
'formatter': 'timestamped',
|
|
},
|
|
'console': {
|
|
'level': config('LOG_LEVEL', default='INFO'),
|
|
'class': 'logging.StreamHandler',
|
|
'formatter': 'timestamped',
|
|
},
|
|
},
|
|
'loggers': {
|
|
'': {
|
|
'handlers': ['console', 'file'],
|
|
'level': config('LOG_LEVEL', default='INFO'),
|
|
'propagate': True,
|
|
},
|
|
},
|
|
'formatters': {
|
|
'timestamped': {
|
|
'format': '[{asctime} {levelname} {module} {funcName}] {message}',
|
|
'style': '{',
|
|
}
|
|
}
|
|
}
|
|
|
|
# Initialise logger now so we can use it in this file
|
|
|
|
LOGGING_CONFIG = None
|
|
logging.config.dictConfig(LOGGING)
|
|
logger = logging.getLogger(__name__) # pylint: disable=invalid-name
|
|
|
|
# Admin panel variables
|
|
|
|
CONSTANCE_CONFIG = {
|
|
'NOTICE_TEXT': (
|
|
'',
|
|
'Text to be displayed in a notice banner at the top of every page.'),
|
|
'NOTICE_CLASS': (
|
|
'alert-warning',
|
|
'CSS class to use for background of notice banner.'),
|
|
'CONSENT_TEXT': (
|
|
'This is template consent text and should have been replaced. Please contact an admin.',
|
|
'Text to be displayed to ask for consent for data collection.'),
|
|
'PERSON_LIST_HELP': (
|
|
'',
|
|
'Help text to display at the top of the people list.'),
|
|
'ORGANISATION_LIST_HELP': (
|
|
'',
|
|
'Help text to display at the top of the organisaton list.'),
|
|
'RELATIONSHIP_FORM_HELP': (
|
|
'',
|
|
'Help text to display at the top of relationship forms.'),
|
|
} # yapf: disable
|
|
|
|
CONSTANCE_CONFIG_FIELDSETS = {
|
|
'Notice Banner': (
|
|
'NOTICE_TEXT',
|
|
'NOTICE_CLASS',
|
|
),
|
|
'Data Collection': (
|
|
'CONSENT_TEXT',
|
|
),
|
|
'Help Text': (
|
|
'PERSON_LIST_HELP',
|
|
'ORGANISATION_LIST_HELP',
|
|
'RELATIONSHIP_FORM_HELP',
|
|
),
|
|
} # yapf: disable
|
|
|
|
CONSTANCE_BACKEND = 'constance.backends.database.DatabaseBackend'
|
|
|
|
# Django Hijack settings
|
|
# See https://django-hijack.readthedocs.io/en/stable/
|
|
|
|
HIJACK_USE_BOOTSTRAP = True
|
|
|
|
# Bootstrap settings
|
|
# See https://django-bootstrap4.readthedocs.io/en/latest/settings.html
|
|
|
|
BOOTSTRAP4 = {
|
|
'include_jquery': 'full',
|
|
}
|
|
|
|
# Email backend settings
|
|
# See https://docs.djangoproject.com/en/3.0/topics/email
|
|
|
|
EMAIL_HOST = config('EMAIL_HOST', default=None)
|
|
DEFAULT_FROM_EMAIL = config(
|
|
'DEFAULT_FROM_EMAIL',
|
|
default=f'{PROJECT_SHORT_NAME}@localhost.localdomain')
|
|
SERVER_EMAIL = DEFAULT_FROM_EMAIL
|
|
|
|
if EMAIL_HOST is None:
|
|
EMAIL_BACKEND = 'django.core.mail.backends.filebased.EmailBackend'
|
|
EMAIL_FILE_PATH = config('EMAIL_FILE_PATH',
|
|
default=str(BASE_DIR.joinpath('mail.log')))
|
|
|
|
else:
|
|
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
|
|
EMAIL_HOST_USER = config('EMAIL_HOST_USER', default=None)
|
|
EMAIL_HOST_PASSWORD = config('EMAIL_HOST_PASSWORD', default=None)
|
|
|
|
EMAIL_PORT = config('EMAIL_PORT', default=25, cast=int)
|
|
EMAIL_USE_TLS = config('EMAIL_USE_TLS',
|
|
default=(EMAIL_PORT == 587),
|
|
cast=bool)
|
|
EMAIL_USE_SSL = config('EMAIL_USE_SSL',
|
|
default=(EMAIL_PORT == 465),
|
|
cast=bool)
|
|
|
|
# Bootstrap Datepicker Plus Settings
|
|
BOOTSTRAP_DATEPICKER_PLUS = {
|
|
"variant_options": {
|
|
"date": {
|
|
"format": "%Y-%m-%d",
|
|
},
|
|
}
|
|
}
|
|
|
|
# Database default automatic primary key
|
|
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
|
|
|
|
# Upstream API keys
|
|
|
|
GOOGLE_MAPS_API_KEY = config('GOOGLE_MAPS_API_KEY', default=None)
|
|
|
|
# Import customisation app settings if present
|
|
|
|
try:
|
|
from custom.settings import (
|
|
CUSTOMISATION_NAME,
|
|
TEMPLATE_NAME_INDEX,
|
|
TEMPLATE_WELCOME_EMAIL_NAME,
|
|
CONSTANCE_CONFIG as constance_config_custom,
|
|
CONSTANCE_CONFIG_FIELDSETS as constance_config_fieldsets_custom
|
|
) # yapf: disable
|
|
|
|
CONSTANCE_CONFIG.update(constance_config_custom)
|
|
CONSTANCE_CONFIG_FIELDSETS.update(constance_config_fieldsets_custom)
|
|
|
|
INSTALLED_APPS.append('custom')
|
|
logger.info("Loaded customisation app: %s", CUSTOMISATION_NAME)
|
|
|
|
except ImportError as exc:
|
|
logger.info("No customisation app loaded: %s", exc)
|
|
|
|
# Set default values if no customisations loaded
|
|
CUSTOMISATION_NAME = None
|
|
TEMPLATE_NAME_INDEX = 'index.html'
|
|
TEMPLATE_WELCOME_EMAIL_NAME = 'welcome-email'
|