Django使用环境变量分离设置环境

2 投票
1 回答
1499 浏览
提问于 2025-04-17 19:57

我有三个Django设置文件,分别是common.pydev.pyprod.py。这三个文件都是从common.py继承而来的。我想把我的数据库密码、数据库网址等信息存储为环境变量,这样就不会出现在我的在线代码库里。

我在StackOverflow和网上查了一些关于环境变量的资料,但我不太确定自己是否理解得很清楚。

我到底应该在我的bash命令行中输入什么呢?比如像export SOMEAPP_DB_USER='someapp'export SOMEAPP_DB_PASSWORD='1234'这样的命令,是不是应该放在我的bash_profile里?

如果我在命令行中输入这个命令,它只对我当前的终端会话有效吗?还是说每次我启动应用的虚拟环境时,它都会永久生效?

我的设置文件应该这样设置吗?

DATABASE_USER = os.environ.get("SOMEAPP_DB_USER", ")
DATABASE_PASSWORD = os.environ.get("SOMEAPP_DB_PASSWORD", ")

1 个回答

3

一个环境是和一个进程关联的,当父进程分叉时,会继承一个副本。你可以让bash在运行其他命令之前,先把一些设置注入到环境中。

下面的命令会在现有的bash环境下运行 ./manage runserver,并且增加两个额外的环境变量 DJANGO_SETTINGS_MODULEMY_DB_PASSWORD

DJANGO_SETTINGS_MODULE=myproject.settings.dev MY_DB_PASSWORD=foo ./manage.py runserver

正如你所建议的,你可以在你的设置文件中使用以下Python代码来提取环境中的值。

import os
db_passwd = os.environ.get('MY_DB_PASSWORD', 'default-db-password')

你可以把密码放在 .profile 文件里,但这可能不是个好主意,因为这样敏感信息和非敏感信息就混在一起了。你还得保护 .profile 文件的权限,否则别人就能轻易读取这个文件,获取你的密码。

我觉得在这种情况下,管理设置的更好方法是有一个单独的文件专门用来存放敏感设置,比如密码。这个文件的权限要保护好,只让需要的人能读,比如你的网页服务器。然后你可以从 settings.py 中读取这个密码文件来获取密码。使用Python的 ConfigParser模块 可能会很有帮助。

如果需要的话,你可以用一个环境变量来指定这个文件的位置,或者如果没有指定,就使用默认位置。

比如: DB_PASSWD_FILE=~/tmp/test_db_passwords.ini ./manage.py runserver

然后在 settings.py

import os
db_passwd_file = os.environ.get('DB_PASSWD_FILE', '/etc/myproject/db_passwords.ini')

# Instantiate a ConfigParser object here to read passwords from db_passwd_file.

这样默认情况下会在系统保护的文件 /etc/myprojecdt/db_passwords.ini 中查找,除非这个位置被 DB_PASSWD_FILE 环境变量覆盖。

在开发过程中,你可以在 .profile 中设置 DB_PASSWD_FILE 指向一个适合开发的路径。这个路径可以通过文件系统权限保护,只让你自己能读。

撰写回答