添加完整学生系统
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
# settings.py
|
||||
# 统一配置入口:所有可变参数都从环境变量 / .env 读取,代码里不再出现硬编码密码。
|
||||
#
|
||||
# 真实业务里"配置"和"代码"必须分离:
|
||||
# 开发 / 测试 / 生产 用的是三套数据库,靠改代码切环境一定会出事故。
|
||||
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
BASE_DIR = Path(__file__).resolve().parent
|
||||
|
||||
|
||||
def _load_dotenv(path: Path) -> None:
|
||||
"""极简 .env 加载器。
|
||||
|
||||
优先使用 python-dotenv;没装则用内置的简易解析,保证零依赖也能跑。
|
||||
"""
|
||||
if not path.exists():
|
||||
return
|
||||
try:
|
||||
from dotenv import load_dotenv # type: ignore
|
||||
|
||||
load_dotenv(path, override=False)
|
||||
return
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
for raw in path.read_text(encoding="utf-8").splitlines():
|
||||
line = raw.strip()
|
||||
if not line or line.startswith("#") or "=" not in line:
|
||||
continue
|
||||
key, _, value = line.partition("=")
|
||||
key, value = key.strip(), value.strip().strip('"').strip("'")
|
||||
# 已存在的真实环境变量优先,不被文件覆盖
|
||||
os.environ.setdefault(key, value)
|
||||
|
||||
|
||||
_load_dotenv(BASE_DIR / ".env")
|
||||
|
||||
|
||||
def _env(key: str, default: str) -> str:
|
||||
value = os.getenv(key)
|
||||
return default if value is None or value == "" else value
|
||||
|
||||
|
||||
def _env_bool(key: str, default: bool) -> bool:
|
||||
return _env(key, str(default)).strip().lower() in ("1", "true", "yes", "on")
|
||||
|
||||
|
||||
def _env_int(key: str, default: int) -> int:
|
||||
try:
|
||||
return int(_env(key, str(default)))
|
||||
except ValueError:
|
||||
return default
|
||||
|
||||
|
||||
class Settings:
|
||||
# ---------- 应用 ----------
|
||||
APP_NAME: str = _env("APP_NAME", "学生管理系统")
|
||||
APP_VERSION: str = _env("APP_VERSION", "1.1.0")
|
||||
DEBUG: bool = _env_bool("DEBUG", True)
|
||||
|
||||
HOST: str = _env("HOST", "127.0.0.1")
|
||||
PORT: int = _env_int("PORT", 8004)
|
||||
|
||||
# API 统一前缀。改这里就能整体换版本,不用一个个改路由。
|
||||
API_PREFIX: str = _env("API_PREFIX", "/api/v1")
|
||||
|
||||
# ---------- 跨域 ----------
|
||||
# 注意:allow_credentials=True 时浏览器【禁止】返回 "*",
|
||||
# 必须显式列出前端域名,否则带 Cookie / 登录态一定失败。
|
||||
CORS_ORIGINS: list[str] = [
|
||||
o.strip()
|
||||
for o in _env(
|
||||
"CORS_ORIGINS",
|
||||
"http://localhost:5500,http://127.0.0.1:5500,"
|
||||
"http://localhost:8000,http://127.0.0.1:8000,"
|
||||
"http://localhost:5173,http://127.0.0.1:5173",
|
||||
).split(",")
|
||||
if o.strip()
|
||||
]
|
||||
|
||||
# ---------- 数据库 ----------
|
||||
DB_HOST: str = _env("DB_HOST", "127.0.0.1")
|
||||
DB_PORT: int = _env_int("DB_PORT", 3306)
|
||||
DB_USER: str = _env("DB_USER", "root")
|
||||
DB_PASSWORD: str = _env("DB_PASSWORD", "")
|
||||
DB_NAME: str = _env("DB_NAME", "student_management_system")
|
||||
DB_CHARSET: str = _env("DB_CHARSET", "utf8mb4")
|
||||
|
||||
DB_ECHO: bool = _env_bool("DB_ECHO", False)
|
||||
DB_POOL_SIZE: int = _env_int("DB_POOL_SIZE", 5)
|
||||
DB_MAX_OVERFLOW: int = _env_int("DB_MAX_OVERFLOW", 10)
|
||||
DB_POOL_RECYCLE: int = _env_int("DB_POOL_RECYCLE", 3600)
|
||||
|
||||
@property
|
||||
def database_url(self) -> str:
|
||||
from urllib.parse import quote_plus
|
||||
|
||||
return (
|
||||
f"mysql+pymysql://{self.DB_USER}:{quote_plus(self.DB_PASSWORD)}"
|
||||
f"@{self.DB_HOST}:{self.DB_PORT}/{self.DB_NAME}"
|
||||
f"?charset={self.DB_CHARSET}"
|
||||
)
|
||||
|
||||
|
||||
settings = Settings()
|
||||
Reference in New Issue
Block a user