为本地开发和生产服务器处理设置的推荐方法是什么?其中一些(如常量等)可以在两者中更改/访问,但其中一些(如静态文件的路径)需要保持不同,因此不应该在每次部署新代码时都重写。
目前,我正在将所有常量添加到settings.py中。但是每次我在本地更改一些常量时,我都必须将其复制到生产服务器并编辑文件以进行特定于生产的更改……:(
编辑:看起来这个问题没有标准答案,我已经接受了最流行的方法。
为本地开发和生产服务器处理设置的推荐方法是什么?其中一些(如常量等)可以在两者中更改/访问,但其中一些(如静态文件的路径)需要保持不同,因此不应该在每次部署新代码时都重写。
目前,我正在将所有常量添加到settings.py中。但是每次我在本地更改一些常量时,我都必须将其复制到生产服务器并编辑文件以进行特定于生产的更改……:(
编辑:看起来这个问题没有标准答案,我已经接受了最流行的方法。
当前回答
大多数解决方案的问题是,您要么将本地设置应用在常用设置之前,要么应用在常用设置之后。
所以不可能覆盖
特定于env的设置定义了memcached池的地址,在主设置文件中,这个值用于配置缓存后端 特定环境的设置添加或删除应用程序/中间件到默认的
同时。
一种解决方案可以使用“ini”风格的配置文件和ConfigParser类实现。它支持多个文件、延迟字符串插值、默认值和许多其他优点。 一旦加载了许多文件,就可以加载更多的文件,它们的值将覆盖之前的文件(如果有的话)。
您可以加载一个或多个配置文件,这取决于计算机地址、环境变量,甚至是先前加载的配置文件中的值。然后只需使用解析后的值填充设置。
我成功使用的一个策略是:
Load a default defaults.ini file Check the machine name, and load all files which matched the reversed FQDN, from the shortest match to the longest match (so, I loaded net.ini, then net.domain.ini, then net.domain.webserver01.ini, each one possibly overriding values of the previous). This account also for developers' machines, so each one could set up its preferred database driver, etc. for local development Check if there is a "cluster name" declared, and in that case load cluster.cluster_name.ini, which can define things like database and cache IPs
举个例子,你可以定义一个“子域”值per-env,然后在默认设置中使用(hostname: %(subdomain).whatever.net)来定义django工作所需的所有必要的主机名和cookie。
这是我能得到的DRY,大多数(现有的)文件只有3或4个设置。除此之外,我还必须管理客户配置,所以存在一组额外的配置文件(包括数据库名称、用户和密码、分配的子域等),每个客户一个或多个。
您可以根据需要将其扩展到低或高,只需在配置文件中放入您想要在每个环境中配置的键,一旦需要新的配置,将先前的值放在默认配置中,并在必要时覆盖它。
该系统已被证明是可靠的,并与版本控制工作良好。它已经被使用很长时间来管理两个独立的应用程序集群(每台机器上有15个或更多的django站点实例),有超过50个客户,集群的大小和成员会根据系统管理员的情绪而变化……
其他回答
创建多个版本的settings.py是12因素应用程序方法论的反模式。 请使用python- decoupling或django-environ。
我使用了上面提到的jpartogi的一个变体,我觉得它更简短:
import platform
from django.core.management import execute_manager
computername = platform.node()
try:
settings = __import__(computername + '_settings')
except ImportError:
import sys
sys.stderr.write("Error: Can't find the file '%r_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" % (computername, __file__))
sys.exit(1)
if __name__ == "__main__":
execute_manager(settings)
基本上,在每台计算机(开发或生产)上,我都有适当的动态加载的hostname_settings.py文件。
记住,settings.py是一个活动代码文件。假设您没有在生产中设置DEBUG(这是一个最佳实践),您可以执行如下操作:
if DEBUG:
STATIC_PATH = /path/to/dev/files
else:
STATIC_PATH = /path/to/production/files
非常基本,但是理论上,您可以根据DEBUG的值或您想使用的任何其他变量或代码检查来提高任何复杂级别。
我发现这里的回答很有帮助。(这个问题是否得到了更明确的解决?上一次回复是在一年前。)在考虑了列出的所有方法之后,我提出了一个在这里没有列出的解决方案。
我的标准是:
所有东西都应该在源代码控制中。我不喜欢精细的东西到处乱放。 理想情况下,将设置保存在一个文件中。如果我不看东西,我就会忘记它们:) 无需部署手动编辑。应该能够用一个fabric命令测试/推送/部署。 避免将开发设置泄漏到生产环境中。 让Django布局尽可能接近“标准”(*咳嗽*)。
我认为打开主机是有意义的,但后来发现真正的问题是针对不同环境的不同设置,并有了一个顿悟时刻。我把这段代码放在settings.py文件的末尾:
try:
os.environ['DJANGO_DEVELOPMENT_SERVER'] # throws error if unset
DEBUG = True
TEMPLATE_DEBUG = True
# This is naive but possible. Could also redeclare full app set to control ordering.
# Note that it requires a list rather than the generated tuple.
INSTALLED_APPS.extend([
'debug_toolbar',
'django_nose',
])
# Production database settings, alternate static/media paths, etc...
except KeyError:
print 'DJANGO_DEVELOPMENT_SERVER environment var not set; using production settings'
这样,应用程序默认为产品设置,这意味着你明确地将你的开发环境“白名单”。忘记在本地设置环境变量要比反过来忘记在生产环境中设置一些内容而使用一些开发设置安全得多。
在本地开发时,无论是在shell中,还是在.bash_profile中,或者其他任何地方:
$ export DJANGO_DEVELOPMENT_SERVER=yep
(或者如果你在Windows上开发,可以通过控制面板或者其他什么工具来设置…Windows总是让它变得如此模糊,以至于你可以设置环境变量。)
使用这种方法,开发设置都在一个(标准)位置,只需在需要的地方覆盖生产设置。任何与开发设置有关的事情都应该完全安全地提交到源代码控制中,而不会对生产产生影响。
我也在与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
也许这样能帮到你。