Django项目的生产设置
我创建了一个叫做 production_settings.py
的文件,在里面放了所有生产环境的变量和对应的值,比如:
import dj_database_url
DATABASES['default'] = dj_database_url.config()
我想声明一个环境变量,名字是
MYPROJECT_PRODUCTION
然后我设置这个变量的方法是
heroku config:add MYPROJECT_PRODUCTION=True
或者 export MYPROJECT_PRODUCTION=True
在 settings.py
文件的最后,我想加上:
import os
if os.environ.has_key('MYPROJECT_PRODUCTION') and os.environ.get('MYPROJECT_PRODUCTION')=='True':
from production_settings import *
这样做对吗?
当我尝试运行 python manage shell
时,出现了导入错误。
export DJANGO_SETTINGS_MODULE='myproject.settings'
export MYPROJECT_PRODUCTION=True
me@ubuntu:~/dev/python/django/myproject$ python manage.py shell
Error: Can't find the file 'settings.py' in the directory containing 'manage.py'. It appears you've customized things.
You'll have to run django-admin.py, passing it your settings module.
(If the file settings.py does indeed exist, it's causing an ImportError somehow.)
而且 manage.py
文件和 settings.py
在同一个文件夹里,但还是出现了错误。
我检查了 echo $MYPROJECT_PRODUCTION
,输出是 True
3 个回答
你有没有把 DATABASES 定义成一个字典?
DATABASES = {}
另外,展示一下你的 heroku logs
。
我建议不要为不同的环境使用不同的设置文件,而是通过环境变量来定制你的设置。这样,你可以默认使用本地开发的设置,并在生产环境中进行覆盖。
比如说数据库和静态/媒体文件的根目录设置。
# Default database URL is a local SQLite instance
DATABASE_URL = 'sqlite:///%s' % os.path.join(os.path.dirname(__file__), 'db.sqlite')
DATABASES = {
'default': dj_database_url.config('DATABASE_URL', default=DATABASE_URL),
}
MEDIA_ROOT = os.environ.get('MEDIA_ROOT',
os.path.join(os.path.dirname(__file__), 'media'))
MEDIA_URL = os.environ.get('MEDIA_URL', '/media/')
STATIC_ROOT = os.environ.get('STATIC_ROOT',
os.path.join(os.path.dirname(__file__), 'static'))
STATIC_URL = os.environ.get('STATIC_URL', '/static/')
通过 heroku config:set
命令,你可以在Heroku上设置任何配置,这样就不需要处理多个设置文件的复杂性。例如:
heroku config:set MEDIA_URL=http://custom-media-server.com/media/
heroku config:set STATIC_URL=http://custom-media-server.com/static/
我还创建了一个自定义的 Django项目模板,它可以从环境变量中获取大部分设置。
你还应该看看 12 Factor Application 网站,特别是关于如何 存储配置 的部分。
我个人会把生产环境的设置放在 settings.py
文件里,然后再加一个 local_settings.py
文件(这个文件会被 .hgignore 排除在版本控制之外)。
我会在 settings.py
文件的最后加上以下内容:
try:
from local_settings import *
except ImportError, e:
pass
然后在我的 local_settings.py
文件里,我会覆盖一些合适的设置 -
DEBUG = True
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'tag',
'USER': 'tag',
'PASSWORD': 'tag',
'HOST': 'localhost',
'PORT': '5432',
}
}
我觉得这个方法用的人还挺多的(我是从同事那学来的,也看到过相关的博客)。
编辑
回应一下 balazs 提出的很好的观点,你可以在这个方法上做一些变动,以保持敏感数据的私密性。也许在 local_settings
导入之后加上以下内容 -
try:
from production_settings import *
except ImportError, e:
pass
然后把 production_settings.py
文件排除在版本控制之外。我想你可能需要用不同的方法来部署 production_settings.py
,但我觉得这也不是太麻烦。