如何通过环境变量管理Django的settings配置

文章导读
很多 Django 项目在部署时会遇到一个尴尬情况:settings.py 里写死的数据库密码在测试和生产环境被频繁覆盖,或者不小心把 SECRET_KEY 传到了 git 仓库。如果你只是本地开发,硬编码配置确实省事,但一旦项目需要在开发、测试、预发布、生产等多个环境运行,硬编码就会频繁导致配置冲突或泄露风险。这时候,把敏感信息放到环境变量里,是行业里常见的做法。
📋 目录
  1. 为什么需要环境变量管理
  2. 推荐的做法:.env 文件与 python-dotenv
  3. 验证配置是否生效
  4. 类型转换与配置检查
  5. 跨平台与命名规范
A A

为什么需要环境变量管理

很多 Django 项目在部署时会遇到一个尴尬情况:settings.py 里写死的数据库密码在测试和生产环境被频繁覆盖,或者不小心把 SECRET_KEY 传到了 git 仓库。如果你只是本地开发,硬编码配置确实省事,但一旦项目需要在开发、测试、预发布、生产等多个环境运行,硬编码就会频繁导致配置冲突或泄露风险。这时候,把敏感信息放到环境变量里,是行业里常见的做法。

推荐的做法:.env 文件与 python-dotenv

推荐在 Django 项目根目录放置一个 .env 文件,通过 python-dotenv 加载。具体操作为:在 manage.py 同级目录安装 dotenv,然后在 manage.py 开头添加 import dotenv; dotenv.load_dotenv(),并在 settings.py 中使用 os.environ.get('DJANGO_SECRET_KEY') 读取变量。注意 .env 文件绝不能提交到版本控制,应在 .gitignore 中添加 .env。生产环境可直接在容器或服务器环境变量中设置,无需 .env 文件。

补充一点:.env 文件里的赋值不要有多余空格,比如 SECRET_KEY = abc 会读取成带空格的 key,应该写成 SECRET_KEY=abc。另外,如果你在 Windows 上开发,环境变量名默认不区分大小写,但 Linux 下区分,所以建议统一用大写加下划线命名,比如 DJANGO_DATABASE_URL,这样跨平台更一致。

验证配置是否生效

验证环境变量是否生效,可以在 settings.py 末尾临时打印某个关键变量:print('SECRET_KEY loaded:', os.environ.get('DJANGO_SECRET_KEY')[:8]),然后运行 python manage.py check,观察输出是否显示正确的前缀片段。确认无误后立刻删除该打印语句。另外,注意不要误用 os.getenv 的默认值,例如 os.getenv('DEBUG', 'False') 会返回字符串 'False',而 Python 中非空字符串为真,导致调试模式意外开启。正确的做法是使用 os.environ.get('DEBUG', 'False') == 'True' 进行布尔转换。

这种临时打印的方法只适合开发时验证,千万别提交到代码里。如果你更稳妥,可以在启动脚本里写个小测试,比如用 python -c "import os; print(os.environ.get('DJANGO_SECRET_KEY'))" 先确认环境变量是否注入。

如何通过环境变量管理Django的settings配置

类型转换与配置检查

使用环境变量时需要注意类型转换问题。Django settings 中的许多配置需要特定类型,比如 DEBUG 是布尔值、ALLOWED_HOSTS 是列表。如果直接从环境变量读取字符串,必须手动转换。例如,ALLOWED_HOSTS 应写成 os.environ.get('ALLOWED_HOSTS', '').split(','),并确保生产环境设置正确的域名逗号分隔字符串。另一个常见坑是误把默认值当成真实值,例如 DATABASE_URL 未设置时回退到 SQLite,但生产环境应强制要求该变量存在,否则启动失败。建议在 settings 中加一段检查,若关键环境变量缺失,直接抛出 ImproperlyConfigured 异常。

具体实现:在 settings.py 底部写一个函数,检查 SECRET_KEYDATABASE_URL 等必须变量是否存在,不存在就 raise ImproperlyConfigured('缺少 DJANGO_SECRET_KEY 环境变量')。这样部署时如果漏设变量,进程会直接报错,不会带着错误配置跑起来。

跨平台与命名规范

环境变量管理还有一些细节值得注意。首先是大小写敏感:Linux/macOS 上 MyVarMYVAR 是两个变量,Windows 下不敏感。统一用大写加下划线命名能避免这个问题。其次是读取频率:避免在多个地方反复调用 os.environ.get(),可以在 settings 模块顶部一次性读取,赋值给模块级别的变量,这样既能减少 I/O 开销,也方便后续引用。

最后,如果你的项目已经使用了环境变量管理,记得定期检查 .env 文件是否真的被 .gitignore 忽略了,可以用 git check-ignore .env 确认。生产环境更简单,直接在容器或系统环境变量里定义,不用保留 .env 文件。