应采用 settings/ 目录结构分层配置:base.py 放公共逻辑,dev.py/prod.py 等继承并覆盖环境敏感项,SECRET_KEY 和数据库凭据须从环境变量读取,禁止硬编码或 fallback,默认值仅设在 base.py,ALLOWED_HOSTS、LOGGING、第三方服务配置须按环境显式设定。

为什么不能只用一个 settings.py
单文件配置在项目小的时候没问题,但一旦要区分开发、测试、预发、生产环境,硬编码 DEBUG=True、写死数据库地址或密钥,很快就会出问题:比如不小心把本地调试用的 EMAIL_BACKEND = 'console' 提到生产,或者把 SECRET_KEY 提交进 Git。Django 本身不强制分层,但官方推荐按环境拆分——核心不是“能不能”,而是“不拆早晚踩坑”。
怎么组织 settings 目录结构才不反人类
常见错误是建一堆平行文件如 settings_dev.py、settings_prod.py,然后靠 DJANGO_SETTINGS_MODULE 切换。这会导致大量重复代码和维护断裂。更稳妥的做法是建 settings/ 包:
myproject/ ├── settings/ │ ├── __init__.py │ ├── base.py # 公共配置(INSTALLED_APPS、MIDDLEWARE 等) │ ├── dev.py # 继承 base,覆盖 DEBUG、数据库、日志等 │ ├── prod.py # 继承 base,禁用 DEBUG,配真实 DB 和缓存 │ └── test.py # 可选,专为 pytest 配置 DATABASES['default']['NAME'] = ':memory:'
关键点:
-
base.py不应包含任何环境敏感值(如SECRET_KEY、DATABASE_URL),只放可复用逻辑 -
dev.py和prod.py必须以from .base import *开头,再做覆盖,避免漏继承 - 所有子配置里不要写
if DEBUG:这类判断——环境差异靠文件分离,不是靠条件分支
如何让 manage.py 自动加载对应环境配置
Django 启动时读取 DJANGO_SETTINGS_MODULE,所以不能指望它自动猜。最轻量的做法是在 manage.py 里加环境判断:
立即学习“Python免费学习笔记(深入)”;
图片提示词生成器?不止如此。 马甲系统 —— 把脑海中的画面,翻译成AI能理解的专业表达。 用得越多,它越懂你:首次需要多问几句确认方向,用久了几乎一说就懂。 用得越多,它越快:缓存机制让后续对话越来越省。 RAG进化:成功案例持续入库,越跑越聪明。 输入「新手指南」查看完整功能介绍
import os
from pathlib import Path
<h1>…… 原有代码</h1><p>if <strong>name</strong> == '<strong>main</strong>':
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings.dev')</p><h1>或根据环境变量切换:</h1><pre class='brush:python;toolbar:false;'># env = os.getenv('DJANGO_ENV', 'dev')
# os.environ.setdefault('DJANGO_SETTINGS_MODULE', f'myproject.settings.{env}')生产部署时,直接在启动命令里指定:
gunicorn myproject.wsgi:application --env DJANGO_SETTINGS_MODULE=myproject.settings.prod
注意:prod.py 必须从环境变量读敏感配置,例如:
import os
SECRET_KEY = os.environ['SECRET_KEY']
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': os.environ['DB_NAME'],
'USER': os.environ['DB_USER'],
# ……
}
}
别把密钥写死在代码里,也别用 os.getenv('KEY', 'fallback')——生产环境缺 KEY 就该立刻报错,而不是悄悄用默认值。
容易被忽略的三个细节
分层之后,以下三点最容易引发线上事故:
-
ALLOWED_HOSTS在prod.py中必须显式列出域名,不能留空或写['*'](Django 会拒绝请求) -
LOGGING配置要随环境变化:开发用ConsoleHandler,生产必须配RotatingFileHandler并确认目录有写权限 - 第三方服务如 Sentry、Redis 缓存,在
base.py里只设默认值(如CACHES = {'default': {...}}),具体连接串全部移到prod.py或dev.py中覆盖
环境配置不是越细越好,关键是把“变”的部分抽出来,把“不变”的逻辑收拢。一旦开始用 settings/ 目录,就别再往 base.py 里塞任何带环境倾向的值——哪怕只是 EMAIL_BACKEND 的默认值,也该由子配置决定。

















