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

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

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


当前回答

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

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

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

其他回答

创建多个版本的settings.py是12因素应用程序方法论的反模式。 请使用python- decoupling或django-environ。

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

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

大多数解决方案的问题是,您要么将本地设置应用在常用设置之前,要么应用在常用设置之后。

所以不可能覆盖

特定于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是一个活动代码文件。假设您没有在生产中设置DEBUG(这是一个最佳实践),您可以执行如下操作:

if DEBUG:
    STATIC_PATH = /path/to/dev/files
else:
    STATIC_PATH = /path/to/production/files

非常基本,但是理论上,您可以根据DEBUG的值或您想使用的任何其他变量或代码检查来提高任何复杂级别。

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

也许这样能帮到你。