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

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

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


当前回答

我也在与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

也许这样能帮到你。

其他回答

我在manage.py中区分它,并创建了两个单独的设置文件:local_settings.py和prod_settings.py。

在manage.py中检查服务器是本地服务器还是生产服务器。如果它是本地服务器,它将加载local_settings.py,如果它是生产服务器,它将加载prod_settings.py。基本上是这样的:

#!/usr/bin/env python
import sys
import socket
from django.core.management import execute_manager 

ipaddress = socket.gethostbyname( socket.gethostname() )
if ipaddress == '127.0.0.1':
    try:
        import local_settings # Assumed to be in the same directory.
        settings = local_settings
    except ImportError:
        import sys
        sys.stderr.write("Error: Can't find the file 'local_settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file local_settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__)
        sys.exit(1)
else:
    try:
        import prod_settings # Assumed to be in the same directory.
        settings = prod_settings    
    except ImportError:
        import sys
        sys.stderr.write("Error: Can't find the file 'prod_settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file prod_settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__)
        sys.exit(1)

if __name__ == "__main__":
    execute_manager(settings)

我发现将设置文件分开到两个单独的文件中更容易,而不是在设置文件中做大量的if。

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

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

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

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

还有Django Classy Settings。我个人是它的忠实粉丝。它是由Django IRC上最活跃的人之一构建的。你可以使用环境变量来设置。

http://django-classy-settings.readthedocs.io/en/latest/

在settings.py:

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

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