""" Django settings for framework project. Generated by 'django-admin startproject' using Django 4.2. For more information on this file, see https://docs.djangoproject.com/en/4.2/topics/settings/ For the full list of settings and their values, see https://docs.djangoproject.com/en/4.2/ref/settings/ """ import time from pathlib import Path import os from app.utils.Secrets import get_runtime_secret # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = Path(__file__).resolve().parent.parent PROJECT_UA = "monitor" PROJECT_BUILT = "monitor built on 2026/08/06" PROJECT_VERSION = "1.003" PROJECT_FLAG = "monitor" # monitor PROJECT_ADMIN_START_TIMESTAMP = int(time.time()) # 软件启动时间戳(秒单位) # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/4.2/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = get_runtime_secret("django_secret_key") MONITOR_INTERNAL_API_SECRET = get_runtime_secret("internal_api_secret") def env_bool(name, default=False): value = os.environ.get(name) if value is None: return default return value.strip().lower() in ("1", "true", "yes", "on") def env_list(name, default=""): return [item.strip() for item in os.environ.get(name, default).split(",") if item.strip()] # SECURITY WARNING: don't run with debug turned on in production! # Production-safe by default. Local development must opt in explicitly. DEBUG = env_bool("MONITOR_DEBUG", False) ALLOWED_HOSTS = env_list("MONITOR_ALLOWED_HOSTS", "127.0.0.1,localhost") # Application definition INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'app' ] MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.middleware.gzip.GZipMiddleware', # 启用 Gzip 压缩,提升响应性能 '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', "app.middleware.SimpleMiddleware", # 拦截器 ] ROOT_URLCONF = 'framework.urls' TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [ os.path.join(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', 'django.template.context_processors.csrf', 'app.context_processors.lang_processor', ], }, }, ] WSGI_APPLICATION = 'framework.wsgi.application' # Database # https://docs.djangoproject.com/en/4.2/ref/settings/#databases DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': BASE_DIR / 'monitor.sqlite3', # SQLite 性能优化:见下方 connection_created 信号中的 PRAGMA 设置 'OPTIONS': { 'timeout': 20, # Python 端连接超时(秒) }, } } # Password validation # https://docs.djangoproject.com/en/4.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', }, ] # Internationalization # https://docs.djangoproject.com/en/2.0/topics/i18n/ #LANGUAGE_CODE = 'zh-hans' #LANGUAGE_CODE = 'en' #TIME_ZONE = 'UTC' USE_I18N = True # 启用国际化 # USE_L10N = True # 启用本地化(如日期、数字格式) USE_TZ = False # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/2.0/howto/static-files/ STATIC_URL = '/static/' STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles') LANGUAGE_CODE = 'zh-hans' TIME_ZONE = 'Asia/Shanghai' """ 静态资源(DEBUG=True:staticfiles 从 STATICFILES_DIRS 直接提供) """ STATICFILES_DIRS = ( os.path.join(BASE_DIR, "static"), ) SESSION_COOKIE_NAME = 'MonitorSessionID' SESSION_EXPIRE_AT_BROWSER_CLOSE=False #会话cookie可以在用户浏览器中保持有效期 True:关闭浏览器则Cookie失效。 DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' # 防止暴力破解 SESSION_COOKIE_AGE=7*24*60*60 # session过期,单位(秒) 7天=7*24*60*60,1小时=1*60*60 SESSION_COOKIE_HTTPONLY = True SESSION_COOKIE_SAMESITE = 'Lax' CSRF_COOKIE_SAMESITE = 'Lax' CSRF_TRUSTED_ORIGINS = env_list("MONITOR_CSRF_TRUSTED_ORIGINS") X_FRAME_OPTIONS = 'SAMEORIGIN' MONITOR_HTTPS = env_bool("MONITOR_HTTPS", False) SESSION_COOKIE_SECURE = MONITOR_HTTPS CSRF_COOKIE_SECURE = MONITOR_HTTPS SECURE_SSL_REDIRECT = MONITOR_HTTPS and env_bool("MONITOR_SSL_REDIRECT", True) SECURE_HSTS_SECONDS = 31536000 if MONITOR_HTTPS else 0 SECURE_HSTS_INCLUDE_SUBDOMAINS = MONITOR_HTTPS SECURE_HSTS_PRELOAD = MONITOR_HTTPS SECURE_CONTENT_TYPE_NOSNIFF = True if env_bool("MONITOR_TRUST_PROXY_HEADERS", False): SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') # Multipart model files are streamed to disk; ordinary request bodies stay bounded. DATA_UPLOAD_MAX_MEMORY_SIZE = int(os.environ.get("MONITOR_MAX_REQUEST_MEMORY", 16 * 1024 * 1024)) FILE_UPLOAD_MAX_MEMORY_SIZE = int(os.environ.get("MONITOR_FILE_MEMORY_THRESHOLD", 2 * 1024 * 1024))