应采用 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 里加环境判断:
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}')
生产部署时,直接在启动命令里指定:
Python 环境工具专业版功能概述Python 环境工具专业版是一项面向实际任务的技能。它将相关步骤、工具调用和结果整理方式集中到统一流程中,帮助使用者更快完成目标并减少重复操作。核心要点使用时应结合输入条件选择合适的执行方式,核对必要参数、依赖环境与输出内容,并按原始要求处理异常情况。该技能适合需要稳定复用相关能力的场景,可作为自动化工作流的一部分,也便于后续检查、调整和扩展。执行完成后建议检查结果是否符合预期,并保留必要记录。使用与执行同时注意输入完整性、执行条件和输出可用性。从功能定位来看,该技能
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 的默认值,也该由子配置决定。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










