settings.py 拆为 base.py 和 local.py 是为解决敏感信息泄露、环境误部署、配置覆盖混乱三大实际问题;base.py 定义共享骨架(如 installed_apps、middleware),secret_key 必须从环境变量读取;local.py 用 from .base import * 确保正确覆盖,且须加入 .gitignore。

settings.py 拆成 base.py 和 local.py 不是为了“看起来规范”,而是为了解决三个实际问题:敏感信息泄露、环境误部署、配置覆盖混乱。不拆,迟早出事。
为什么直接改 settings.py 会触发生产事故
最常见错误是把 DEBUG=True 或 ALLOWED_HOSTS=['*'] 提交到主干分支,然后被自动部署到生产环境——结果就是调试页面暴露、SQL注入风险放大、CSRF校验失效。Django 官方明确警告:DEBUG=False 时 ALLOWED_HOSTS 必须显式设置,否则 500 错误静默发生,连日志都不留。
- 本地开发需要
DEBUG=True、sqlite3、宽松的中间件(如django-debug-toolbar) - 生产环境必须禁用调试、用
postgresql、启用 HTTPS 中间件、限制 host 白名单 - 两者共用一个文件,靠注释/条件判断切换,极易漏改、误提交、CI/CD 覆盖失败
base.py 应该只放什么,不能放什么
base.py 是所有环境共享的“骨架”,它定义不变量,不是“默认值集合”。放错内容会导致子配置无法覆盖或行为异常。
快速生成专业的 Python 脚本和应用代码。一键创建完整项目结构,支持CLI、API、爬虫、Bot、Django等多种项目类型,包含完整的项目结构、配置文件、依赖管理、测试、README和文档。
- ✅ 必须放:
INSTALLED_APPS公共部分、MIDDLEWARE基础链、TEMPLATES公共选项、BASE_DIR、SECRET_KEY(但应从环境变量读取,而非硬编码) - ❌ 绝对不能放:
DEBUG、DATABASES、ALLOWED_HOSTS、LOGGING的具体 handler 配置、EMAIL_BACKEND - ⚠️ 特别注意:
SECRET_KEY在base.py中必须写成os.getenv('DJANGO_SECRET_KEY'),而不是字符串字面量;否则local.py无法安全覆盖
为什么 local.py 要用 from .base import * 开头
这不是偷懒,而是保证继承顺序和覆盖语义正确。Django 配置加载是纯 Python 执行过程,顺序决定覆盖结果。
- 如果
local.py不导入base,你就得手动复制所有公共配置,一旦base更新,local就立刻失步 - 用
from .base import *后,再写DEBUG = True,才是真正的“覆盖”——Python 会用新值替换旧绑定 - 但要注意:像
INSTALLED_APPS += ['debug_toolbar']这种追加操作是安全的;而INSTALLED_APPS = [...]全量重写会丢掉base里的基础 app(如django.contrib.admin) -
local.py必须加进.gitignore,且不应包含任何生产敏感字段(如数据库密码),这些应走环境变量
拆分后怎么指定运行环境
靠 DJANGO_SETTINGS_MODULE 环境变量或 --settings 参数控制,不是靠文件名自动识别。
- 开发时:
python manage.py runserver --settings=settings.local - 生产部署时(如 gunicorn):
gunicorn myproject.wsgi:application --env DJANGO_SETTINGS_MODULE=settings.production - CI/CD 流水线里必须显式设置该变量,否则默认 fallback 到
settings.py,可能加载错误配置 - 别依赖
__init__.py自动合并——它容易掩盖覆盖失败(比如某个optional('production.py')实际没被 include,却没报错)
local.py 是否真的生效了。上线前跑一次 python manage.py diffsettings(需安装 django-extensions),比看文档管用十倍。Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










