如何管理Django中的本地与生产设置?

349 投票
23 回答
127890 浏览
提问于 2025-04-15 15:23

在本地开发和生产服务器上,处理设置的推荐方法是什么呢?有些设置(比如常量等)在两者中都可以更改或访问,但有些设置(比如静态文件的路径)需要保持不同,因此每次部署新代码时不应该被覆盖。

目前,我把所有常量都放在 settings.py 文件里。但是每次我在本地修改某个常量时,都得把它复制到生产服务器上,并且还要修改文件以适应生产环境的需求…… :(

编辑:看起来这个问题没有标准答案,我接受了最流行的方法。

23 个回答

76

不要使用 settings.py,可以试试这个结构:

.
└── settings/
    ├── __init__.py  <= not versioned
    ├── common.py
    ├── dev.py
    └── prod.py

common.py 是你大部分配置的地方。

prod.pycommon.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..."

我喜欢这个方案的原因是:

  1. 除了秘密信息,其他所有内容都在你的版本控制系统里。
  2. 大部分配置都集中在一个地方:common.py
  3. 生产环境的特定设置放在 prod.py,开发环境的特定设置放在 dev.py。这样很简单。
  4. 你可以在 prod.pydev.py 中覆盖 common.py 的内容,也可以在 __init__.py 中覆盖任何内容。
  5. 这就是简单的 Python,没有复杂的重新导入技巧。
329

《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.pyproduction.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上发布了一个示例项目的布局模板

136

settings.py 文件里:

try:
    from local_settings import *
except ImportError as e:
    pass

你可以在 local_settings.py 文件中覆盖需要的设置;这个文件应该不放在你的版本控制里。因为你提到要复制,我猜想你可能根本就没有使用版本控制;)

撰写回答