
Django 本身不原生支持 .env 文件,需借助 django-environ 等第三方库加载环境变量;修改后必须重启服务且确保加载逻辑正确执行,否则变量不会更新。
django 本身不原生支持 `.env` 文件,需借助 `django-environ` 等第三方库加载环境变量;修改后必须重启服务且确保加载逻辑正确执行,否则变量不会更新。
在 Django 项目中使用 .env 文件管理敏感配置(如数据库凭证、密钥)是行业最佳实践,但许多开发者会遇到“改了 .env 却没生效”的问题——即使文件位置正确、语法无误、服务已重启,新值仍不被读取。根本原因在于:Django 启动时仅在 settings 模块首次导入时加载一次环境变量,且默认不解析 .env 文件。
✅ 正确做法:集成 django-environ
-
安装依赖
pip install django-environ
-
在 settings.py 中配置加载逻辑(关键!)
将以下代码置于 BASE_DIR 定义之后、任何使用环境变量的配置之前(例如 DATABASES 之前):import os import environ # 初始化 environ 实例 env = environ.Env() # 告知 environ 从项目根目录下的 .env 文件读取变量 environ.Env.read_env(os.path.join(BASE_DIR, '.env'))
⚠️ 注意:environ.Env.read_env() 必须显式调用一次,且路径必须准确(推荐用 os.path.join(BASE_DIR, '.env') 而非相对路径)。
-
安全读取变量并设置默认值
使用 env('KEY', default='fallback') 替代 os.environ.get(),它更健壮(支持类型转换、必填校验等):DATABASES = { "default": { "ENGINE": "django.db.backends.mysql", "NAME": env("DB_NAME"), # 必填项,缺失时报错 "USER": env("DB_USER", default="root"), "PASSWORD": env("DB_PASSWORD", default=""), "HOST": env("DB_HOST", default="localhost"), "PORT": env.int("DB_PORT", default=3306), # 自动转为 int } }
? 验证是否加载成功?
在 settings.py 底部临时添加调试语句(部署前务必删除):
print("✅ Loaded DB_NAME:", env("DB_NAME", default="NOT_SET"))
print("✅ All env keys:", list(env.ENVIRON.keys()))启动服务时观察终端输出,确认值与 .env 一致。
? 常见失效原因及解决方案
❌ 加载时机错误:environ.Env.read_env() 放在 DATABASES 之后 → 变量尚未加载,读取为空。
✅ 修复:严格置于 BASE_DIR 之后、所有配置之前。❌ .env 文件编码或格式问题:含 BOM 头、Windows 换行符(\r\n)、空格缩进、未引号的值含空格。
✅ 修复:用 VS Code 等编辑器保存为 UTF-8 无 BOM,确保每行形如 KEY=value(无空格、无引号除非含特殊字符)。❌ 多进程/热重载干扰:开发服务器(如 runserver)在代码变更时自动重载,但 .env 变更不会触发重载。
✅ 修复:必须手动终止并重新运行 python manage.py runserver;不要依赖保存即刷新。❌ IDE 缓存或虚拟环境混淆:PyCharm 可能缓存旧环境变量,或激活了错误的 venv。
✅ 修复:重启 IDE,确认终端中 which python 指向项目虚拟环境。
✅ 最佳实践总结
- 始终为所有环境变量提供 default 值或使用 env(..., default=...),避免 KeyError;
- 生产环境建议用系统级环境变量替代 .env(更安全),.env 仅用于本地开发;
- 将 .env 加入 .gitignore,严禁提交到版本库;
- 使用 env.bool(), env.list(), env.json() 等方法提升类型安全性。
完成上述配置后,每次修改 .env,只需彻底重启 Django 开发服务器,变量即可立即生效——无需清缓存、无需修改代码,真正实现配置与代码的解耦。







