Files
dbstorage/dbapp/dbapp/settings/base.py

289 lines
9.1 KiB
Python

"""
Django settings for dbapp project.
Base settings shared across all environments.
Environment-specific settings are in development.py and production.py
"""
import os
from pathlib import Path
from dotenv import load_dotenv
# Load environment variables from .env file
load_dotenv()
# ============================================================================
# PATH CONFIGURATION
# ============================================================================
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
# GDAL/GEOS configuration for Windows
if os.name == "nt":
OSGEO4W = r"C:\Program Files\OSGeo4W"
assert os.path.isdir(OSGEO4W), "Directory does not exist: " + OSGEO4W
os.environ["OSGEO4W_ROOT"] = OSGEO4W
os.environ["PROJ_LIB"] = os.path.join(OSGEO4W, r"share\proj")
os.environ["PATH"] = OSGEO4W + r"\bin;" + os.environ["PATH"]
# ============================================================================
# SECURITY SETTINGS
# ============================================================================
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = os.getenv(
"SECRET_KEY", "django-insecure-7etj5f7buo2a57xv=w3^&llusq8rii7b_gd)9$t_1xcnao!^tq"
)
# SECURITY WARNING: don't run with debug turned on in production!
# This should be overridden in environment-specific settings
DEBUG = False
# Allowed hosts - should be overridden in environment-specific settings
ALLOWED_HOSTS = []
# ============================================================================
# APPLICATION DEFINITION
# ============================================================================
INSTALLED_APPS = [
# Django Autocomplete Light (must be before admin)
"dal",
"dal_select2",
# Admin interface customization
"admin_interface",
"colorfield",
# Django GIS
"django.contrib.gis",
# Django core apps
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"django.contrib.humanize",
# Third-party apps
"leaflet",
"dynamic_raw_id",
"rangefilter",
"django_admin_multiple_choice_list_filter",
"more_admin_filters",
"import_export",
"django_celery_results",
# Project apps
"mainapp",
"mapsapp",
"lyngsatapp",
]
# AUTH_USER_MODEL = 'mainapp.CustomUser'
# ============================================================================
# MIDDLEWARE CONFIGURATION
# ============================================================================
MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.locale.LocaleMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
]
ROOT_URLCONF = "dbapp.urls"
# ============================================================================
# TEMPLATES CONFIGURATION
# ============================================================================
TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [
BASE_DIR / "templates",
],
"APP_DIRS": True,
"OPTIONS": {
"context_processors": [
"django.template.context_processors.debug",
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
],
},
},
]
WSGI_APPLICATION = "dbapp.wsgi.application"
# ============================================================================
# DATABASE CONFIGURATION
# ============================================================================
DATABASES = {
"default": {
"ENGINE": os.getenv("DB_ENGINE", "django.contrib.gis.db.backends.postgis"),
"NAME": os.getenv("DB_NAME", "db"),
"USER": os.getenv("DB_USER", "user"),
"PASSWORD": os.getenv("DB_PASSWORD", "password"),
"HOST": os.getenv("DB_HOST", "localhost"),
"PORT": os.getenv("DB_PORT", "5432"),
}
}
# ============================================================================
# PASSWORD VALIDATION
# ============================================================================
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",
},
]
# ============================================================================
# INTERNATIONALIZATION
# ============================================================================
LANGUAGE_CODE = "ru"
TIME_ZONE = "Europe/Moscow"
USE_I18N = True
USE_TZ = True
# ============================================================================
# AUTHENTICATION CONFIGURATION
# ============================================================================
LOGIN_URL = "login"
LOGIN_REDIRECT_URL = "mainapp:home"
LOGOUT_REDIRECT_URL = "mainapp:home"
# ============================================================================
# STATIC FILES CONFIGURATION
# ============================================================================
STATIC_URL = "/static/"
STATICFILES_DIRS = [
BASE_DIR.parent / "static",
]
# STATIC_ROOT will be set in production.py
# ============================================================================
# DEFAULT SETTINGS
# ============================================================================
# Default primary key field type
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
# ============================================================================
# THIRD-PARTY APP CONFIGURATION
# ============================================================================
# Admin Interface
X_FRAME_OPTIONS = "SAMEORIGIN"
SILENCED_SYSTEM_CHECKS = ["security.W019"]
# Leaflet Configuration
LEAFLET_CONFIG = {
"ATTRIBUTION_PREFIX": "",
"TILES": [
(
"Satellite",
"https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}",
{"attribution": "© Esri", "maxZoom": 16},
),
(
"Streets",
"http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
{
"attribution": '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>'
},
),
],
}
# ============================================================================
# CACHE CONFIGURATION
# ============================================================================
# Redis Cache Configuration
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": os.getenv("REDIS_URL", "redis://localhost:6379/1"),
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
"CONNECTION_POOL_CLASS_KWARGS": {
"max_connections": 50,
"retry_on_timeout": True,
},
"SOCKET_CONNECT_TIMEOUT": 5,
"SOCKET_TIMEOUT": 5,
},
"KEY_PREFIX": "dbapp",
"TIMEOUT": 300, # Default timeout 5 minutes
}
}
# ============================================================================
# CELERY CONFIGURATION
# ============================================================================
# Celery Configuration Options
CELERY_BROKER_URL = os.getenv("CELERY_BROKER_URL", "redis://localhost:6379/0")
CELERY_RESULT_BACKEND = os.getenv(
"CELERY_BROKER_URL", "redis://localhost:6379/0"
) # Use Redis for results
CELERY_CACHE_BACKEND = "default"
# Celery Task Configuration
CELERY_TASK_TRACK_STARTED = True
CELERY_TASK_TIME_LIMIT = 30 * 60 # 30 minutes
CELERY_TASK_SOFT_TIME_LIMIT = 25 * 60 # 25 minutes
CELERY_TASK_ALWAYS_EAGER = False # Set to True for synchronous execution in development
# Celery Beat Configuration (for periodic tasks)
CELERY_BEAT_SCHEDULER = "django_celery_beat.schedulers:DatabaseScheduler"
# Celery Result Backend Configuration
CELERY_RESULT_EXTENDED = True
CELERY_RESULT_EXPIRES = 3600 # Results expire after 1 hour
# Celery Logging
CELERY_WORKER_HIJACK_ROOT_LOGGER = False
CELERY_WORKER_LOG_FORMAT = "[%(asctime)s: %(levelname)s/%(processName)s] %(message)s"
CELERY_WORKER_TASK_LOG_FORMAT = "[%(asctime)s: %(levelname)s/%(processName)s][%(task_name)s(%(task_id)s)] %(message)s"
# Celery Accept Content
CELERY_ACCEPT_CONTENT = ["json"]
CELERY_TASK_SERIALIZER = "json"
CELERY_RESULT_SERIALIZER = "json"
CELERY_TIMEZONE = TIME_ZONE
# Celery Exception Handling
CELERY_TASK_IGNORE_RESULT = False
CELERY_TASK_STORE_ERRORS_EVEN_IF_IGNORED = True