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

目前,我正在将所有常量添加到settings.py中。但是每次我在本地更改一些常量时,我都必须将其复制到生产服务器并编辑文件以进行特定于生产的更改……:(

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


当前回答

不要使用settings.py,而是使用下面的布局:

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

py是您的大部分配置所在的位置。

py从common中导入所有内容,并覆盖它需要覆盖的内容:

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。没有重新导入黑客。

其他回答

在settings.py:

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

你可以覆盖local_settings.py;它应该不在你的版本控制范围之内。但既然你提到了复制,我猜你没有使用;)

我对这个问题的解决方案在某种程度上也是这里已经提到的一些解决方案的混合:

我保留了一个名为local_settings.py的文件,其内容为USING_LOCAL = True在dev中,USING_LOCAL = False在prod中 在settings.py中,我对该文件进行导入以获得USING_LOCAL设置

然后我将所有与环境相关的设置都基于此:

DEBUG = USING_LOCAL
if USING_LOCAL:
    # dev database settings
else:
    # prod database settings

我更喜欢这样,而不是有两个单独的settings.py文件,我需要维护,因为我可以将我的设置结构化地保存在一个文件中,而不是将它们分布在几个文件中。就像这样,当我更新一个设置时,我不会忘记在两个环境中都这样做。

当然每种方法都有它的缺点,这种方法也不例外。这里的问题是,无论何时将更改推到生产环境中,我都不能覆盖local_settings.py文件,这意味着我不能盲目地复制所有文件,但这是我可以接受的。

我认为最好的解决方案是@T提出的。但是我不知道为什么在Django中不使用DEBUG标志。我写下面的代码为我的网站:

if DEBUG:
    from .local_settings import *

简单的解决方案总是比复杂的解决方案好。

我也在与Laravel合作,我喜欢那里的实现。我试着模仿它,并将其与T. Stone提出的解决方案结合起来(见上文):

PRODUCTION_SERVERS = ['*.webfaction.com','*.whatever.com',]

def check_env():
    for item in PRODUCTION_SERVERS:
        match = re.match(r"(^." + item + "$)", socket.gethostname())
        if match:
            return True

if check_env():
    PRODUCTION = True
else:
    PRODUCTION = False

DEBUG = not PRODUCTION

也许这样能帮到你。

如果你愿意,可以选择维护不同的文件: 如果您正在使用git或任何其他VCS将代码从本地推送到服务器,您可以将设置文件添加到.gitignore。

这将允许您在两个地方有不同的内容而没有任何问题。所以在服务器上,你可以配置一个独立版本的settings.py,任何在本地所做的更改都不会反映在服务器上,反之亦然。

此外,它将删除settings.py文件从github也,大错误,这我已经看到许多新手做。