CI / test (pull_request) Successful in 7s
Replace hardcoded settings with environment-driven config, add Docker compose for local and production deploys, migrate from pip to uv, and split Gitea workflows so PRs run tests only while master pushes deploy.
170 lines
4.8 KiB
Python
170 lines
4.8 KiB
Python
"""Shared Django settings for all environments."""
|
|
|
|
import os
|
|
from pathlib import Path
|
|
from urllib.parse import urlparse
|
|
|
|
BASE_DIR = Path(__file__).resolve().parent.parent.parent
|
|
|
|
|
|
def env(key: str, default: str | None = None) -> str | None:
|
|
return os.environ.get(key, default)
|
|
|
|
|
|
def env_bool(key: str, default: bool = False) -> bool:
|
|
value = os.environ.get(key)
|
|
if value is None:
|
|
return default
|
|
return value.lower() in {"1", "true", "yes", "on"}
|
|
|
|
|
|
def env_list(key: str, default: str = "") -> list[str]:
|
|
value = os.environ.get(key, default)
|
|
if not value:
|
|
return []
|
|
return [item.strip() for item in value.split(",") if item.strip()]
|
|
|
|
|
|
def database_config() -> dict:
|
|
database_url = env("DATABASE_URL")
|
|
if database_url:
|
|
parsed = urlparse(database_url)
|
|
return {
|
|
"default": {
|
|
"ENGINE": "django.db.backends.postgresql",
|
|
"NAME": parsed.path.lstrip("/"),
|
|
"USER": parsed.username or "",
|
|
"PASSWORD": parsed.password or "",
|
|
"HOST": parsed.hostname or "",
|
|
"PORT": str(parsed.port or 5432),
|
|
}
|
|
}
|
|
|
|
if env("DB_HOST"):
|
|
return {
|
|
"default": {
|
|
"ENGINE": "django.db.backends.postgresql",
|
|
"NAME": env("DB_NAME", "company_site"),
|
|
"USER": env("DB_USER", "company_site"),
|
|
"PASSWORD": env("DB_PASSWORD", ""),
|
|
"HOST": env("DB_HOST"),
|
|
"PORT": env("DB_PORT", "5432"),
|
|
}
|
|
}
|
|
|
|
return {
|
|
"default": {
|
|
"ENGINE": "django.db.backends.sqlite3",
|
|
"NAME": BASE_DIR / "db.sqlite3",
|
|
}
|
|
}
|
|
|
|
|
|
SECRET_KEY = env(
|
|
"DJANGO_SECRET_KEY",
|
|
"django-insecure-dev-only-change-me-before-production",
|
|
)
|
|
|
|
DEBUG = env_bool("DJANGO_DEBUG", False)
|
|
TIANJI_ENABLED = env_bool("TIANJI_ENABLED", not DEBUG)
|
|
|
|
allowed_hosts = env_list("DJANGO_ALLOWED_HOSTS", "*")
|
|
ALLOWED_HOSTS = allowed_hosts if allowed_hosts else ["*"]
|
|
|
|
INSTALLED_APPS = [
|
|
"public.apps.PublicConfig",
|
|
"financial.apps.FinancialConfig",
|
|
"planning.apps.PlanningConfig",
|
|
"django.contrib.admin",
|
|
"django.contrib.auth",
|
|
"django.contrib.contenttypes",
|
|
"django.contrib.sessions",
|
|
"django.contrib.messages",
|
|
"whitenoise.runserver_nostatic",
|
|
"django.contrib.staticfiles",
|
|
"phonenumber_field",
|
|
"django_recaptcha",
|
|
]
|
|
|
|
MIDDLEWARE = [
|
|
"django.middleware.security.SecurityMiddleware",
|
|
"whitenoise.middleware.WhiteNoiseMiddleware",
|
|
"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",
|
|
]
|
|
|
|
ROOT_URLCONF = "company_site.urls"
|
|
|
|
TEMPLATES = [
|
|
{
|
|
"BACKEND": "django.template.backends.django.DjangoTemplates",
|
|
"DIRS": [],
|
|
"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",
|
|
"public.context_processors.tianji_tracking",
|
|
],
|
|
},
|
|
},
|
|
]
|
|
|
|
WSGI_APPLICATION = "company_site.wsgi.application"
|
|
|
|
DATABASES = database_config()
|
|
|
|
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",
|
|
},
|
|
]
|
|
|
|
LANGUAGE_CODE = "en-us"
|
|
TIME_ZONE = "UTC"
|
|
USE_I18N = True
|
|
USE_TZ = True
|
|
|
|
STATIC_URL = "static/"
|
|
STATIC_ROOT = BASE_DIR / "staticfiles"
|
|
STORAGES = {
|
|
"staticfiles": {
|
|
"BACKEND": "whitenoise.storage.CompressedManifestStaticFilesStorage",
|
|
},
|
|
}
|
|
|
|
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
|
|
|
|
RECAPTCHA_PUBLIC_KEY = env("RECAPTCHA_PUBLIC_KEY", "")
|
|
RECAPTCHA_PRIVATE_KEY = env("RECAPTCHA_PRIVATE_KEY", "")
|
|
|
|
EMAIL_HOST = env("EMAIL_HOST", "mail.smtp2go.com")
|
|
EMAIL_HOST_USER = env("EMAIL_HOST_USER", "")
|
|
EMAIL_HOST_PASSWORD = env("EMAIL_HOST_PASSWORD", "")
|
|
EMAIL_PORT = int(env("EMAIL_PORT", "2525"))
|
|
EMAIL_USE_TLS = env_bool("EMAIL_USE_TLS", True)
|
|
|
|
LOGIN_REDIRECT_URL = "/"
|
|
LOGOUT_REDIRECT_URL = "/"
|
|
|
|
TIANJI_TRACKER_URL = env(
|
|
"TIANJI_TRACKER_URL",
|
|
"https://tianji.aimloperations.com/tracker.js",
|
|
)
|
|
TIANJI_WEBSITE_ID = env("TIANJI_WEBSITE_ID", "")
|