如何管理Django中的本地与生产设置?
在本地开发和生产服务器上,处理设置的推荐方法是什么呢?有些设置(比如常量等)在两者中都可以更改或访问,但有些设置(比如静态文件的路径)需要保持不同,因此每次部署新代码时不应该被覆盖。
目前,我把所有常量都放在 settings.py
文件里。但是每次我在本地修改某个常量时,都得把它复制到生产服务器上,并且还要修改文件以适应生产环境的需求…… :(
编辑:看起来这个问题没有标准答案,我接受了最流行的方法。
23 个回答
不要使用 settings.py
,可以试试这个结构:
.
└── settings/
├── __init__.py <= not versioned
├── common.py
├── dev.py
└── prod.py
common.py
是你大部分配置的地方。
prod.py
从 common.py
导入所有内容,并根据需要进行修改:
from __future__ import absolute_import # optional, but I like it
from .common import *
# Production overrides
DEBUG = False
#...
同样,dev.py
也从 common.py
导入所有内容,并进行必要的修改。
最后,__init__.py
是你决定加载哪些设置的地方,同时也是存放秘密信息的地方(所以这个文件不应该被版本控制):
from __future__ import absolute_import
from .prod import * # or .dev if you want dev
##### DJANGO SECRETS
SECRET_KEY = '(3gd6shenud@&57...'
DATABASES['default']['PASSWORD'] = 'f9kGH...'
##### OTHER SECRETS
AWS_SECRET_ACCESS_KEY = "h50fH..."
我喜欢这个方案的原因是:
- 除了秘密信息,其他所有内容都在你的版本控制系统里。
- 大部分配置都集中在一个地方:
common.py
。 - 生产环境的特定设置放在
prod.py
,开发环境的特定设置放在dev.py
。这样很简单。 - 你可以在
prod.py
或dev.py
中覆盖common.py
的内容,也可以在__init__.py
中覆盖任何内容。 - 这就是简单的 Python,没有复杂的重新导入技巧。
《Django最佳实践:Django 1.5的两勺子》建议对你的设置文件使用版本控制,并把这些文件放在一个单独的文件夹里:
project/
app1/
app2/
project/
__init__.py
settings/
__init__.py
base.py
local.py
production.py
manage.py
base.py
文件里包含了一些通用的设置,比如媒体文件的根目录(MEDIA_ROOT)或者管理员设置(ADMIN);而local.py
和production.py
则是针对具体网站的设置:
在基础设置文件settings/base.py
中:
INSTALLED_APPS = (
# common apps...
)
在本地开发的设置文件settings/local.py
中:
from project.settings.base import *
DEBUG = True
INSTALLED_APPS += (
'debug_toolbar', # and other apps for local development
)
在生产环境的设置文件settings/production.py
中:
from project.settings.base import *
DEBUG = False
INSTALLED_APPS += (
# other apps for production site
)
然后,当你运行Django时,需要加上--settings
这个选项:
# Running django for local development
$ ./manage.py runserver 0:8000 --settings=project.settings.local
# Running django shell on the production site
$ ./manage.py shell --settings=project.settings.production
这本书的作者还在Github上发布了一个示例项目的布局模板。
在 settings.py
文件里:
try:
from local_settings import *
except ImportError as e:
pass
你可以在 local_settings.py
文件中覆盖需要的设置;这个文件应该不放在你的版本控制里。因为你提到要复制,我猜想你可能根本就没有使用版本控制;)