如何在Django中管理本地和生产环境设置?

348

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

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

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


3
请参考 https://dev59.com/vnVD5IYBdhLWcg3wGXlI,了解如何配置Django以进行简单的开发和部署。 - Mark Lavin
请查看django-configurations - JJD
2
被广泛接受的方法不再是最流行的。 - Daniel
2
django-split-settings非常易于使用。它不需要重写任何默认设置。 - sobolevn
你应该使用base.py文件,在你的local.py中添加"from .base import *",在你的production.py中也是同样的操作,需要用以下命令运行你的项目:python manage.py runserver --settings=project_name.settings.local - Roberth Solís
23个回答

329

《Django最佳实践:第二版》建议为您的设置文件使用版本控制,并将这些文件存储在一个单独的目录中:

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上发布了一个样例项目布局模板(链接)


70
请注意,您可以设置环境变量DJANGO_SETTINGS_MODULE来代替每次使用 --settings。这种方法很适合在Heroku等平台上使用:将它全局设置为生产环境,然后在您的.env文件中覆盖为开发环境。请注意,不要更改原意。 - Simon Weber
9
在这里使用 DJANGO_SETTINGS_MODULE 环境变量是最好的思路,感谢 Simon。 - kibibu
22
你可能需要将BASE_DIR设置更改为os.path.dirname(os.path.realpath(os.path.dirname(__file__) + "/.."))。该设置旨在使路径更准确且不易出错。 - Petr Peller
5
根据 Django 文档,你需要导入 from django.conf import settings 这个模块,它是一个对象,用于抽象出设置的接口,并将代码与设置的位置解耦。详情请参考:https://docs.djangoproject.com/en/dev/topics/settings/#using-settings-in-python-code - user9903
3
@PetrPeller 这是更简洁的写法:BASE_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', '..')) - Amir Ali Akbari
显示剩余10条评论

136

settings.py 文件中:

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

你可以在 local_settings.py 中覆盖需要的内容;它应该不包含在你的版本控制中。但既然你提到了复制,我猜你没用过;)


8
这就是我的做法 - 在settings.py的末尾添加这些行,以便它们可以覆盖默认设置。 - daonb
66
这种方法意味着您在开发和生产中运行未经版本控制的代码,而且每个开发人员都有不同的代码库。我称之为反模式。 - pydanny
8
问题在于 Django 把配置存储在 .py 文件中。你不能期望所有开发者和生产服务器都使用相同的设置,因此需要修改这个 .py 文件或实现一些替代方案(如 .ini 文件、环境变量等)。 - Tupteq
4
我更喜欢将模块命名为settings_local而不是local_settings,以便在按字母排序的文件夹列表中与settings.py分组。使用.gitignoresettings_local.py排除在版本控制之外,因为凭据不属于Git,以防意外公开它们。我保留一个名为settings_local.py.txt的模板文件放在git中。 - fmalina
4
你好,我可以回答一下为什么要写成except ImportError as e: 而不只是 except ImportError:吗?其实这两种写法都可以,但是加上as e的话,可以把捕捉到的错误信息存储在变量e中,方便后续处理或输出。 - Costantin
显示剩余10条评论

76

不要使用settings.py,而是使用这个布局:

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

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

prod.py 导入了来自 common 的所有内容,并覆盖了它需要覆盖的任何内容:

from __future__ import absolute_import # optional, but I like it
from .common import *

# Production overrides
DEBUG = False
#...

同样地,dev.pycommon.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,没有重新导入的hack。

2
我仍在努力弄清楚我的project.wsgi和manage.py文件中应该设置什么设置文件。你能为此提供一些帮助吗?具体来说,在我的manage.py文件中,我有os.environ.setdefault("DJANGO_SETTINGS_MODULE", "foobar.settings"),其中foobar是一个带有__init__.py文件的文件夹,而settings是一个带有__init__.py文件的文件夹,其中包含我的机密信息并导入dev.py,然后导入common.py。 编辑 算了,我没有安装所需的模块。我的错!这个方法很好用!! - teewuane
5
两件事情: 1) 最好在dev.py中设置Debug=True,而不是在prod.py中设置为False。2) 而不是在__init__.py中切换,可以使用DJANGO_SETTINGS_MODULE环境变量进行切换。这将有助于PAAS部署(例如Heroku)。 - Rob Grant
当我在django1.8.4中使用这个设置并尝试运行服务器时,我会收到“django.core.exceptions.ImproperlyConfigured:SECRET_KEY设置不能为空”的提示,即使我在__init__.py文件中有SECRET_KEY。 我是否漏掉了什么东西? - polarcare
使用类似 AWS_SECRET_ACCESS_KEY = os.getenv("AWS_SECRET_ACCESS_KEY") 这样的东西不是更安全吗?老实说,我知道你为什么不想将其版本化,但另一种选择是从环境中获取它。这当然会引发设置环境变量的问题,但可以留给您的部署机制来处理,不是吗? - JL Peyret

20
我使用了Harper Shelby发布的“if DEBUG”风格的设置,稍作修改。显然,根据环境(win/linux/等),代码可能需要进行一些微调。
过去我曾经使用“if DEBUG”,但是有时我需要使用 DEUBG=False 进行测试。我真正想要区分的是生产环境还是开发环境,这让我可以自由选择DEBUG级别。
PRODUCTION_SERVERS = ['WEBSERVER1','WEBSERVER2',]
if os.environ['COMPUTERNAME'] in PRODUCTION_SERVERS:
    PRODUCTION = True
else:
    PRODUCTION = False

DEBUG = not PRODUCTION
TEMPLATE_DEBUG = DEBUG

# ...

if PRODUCTION:
    DATABASE_HOST = '192.168.1.1'
else:
    DATABASE_HOST = 'localhost'

我仍然认为这种设置方式还有待改进。我没有看到任何一种可处理所有基础事项且同时不需要完全麻烦的Django设置方法(我不喜欢五个设置文件的方法)。


这就是Django的设置作为实际代码文件的好处,我之前也有所暗示。虽然我自己没有尝试过这样的操作,但这绝对是一种比我的解决方案更好的通用解决方案。 - Harper Shelby
4
我第一次遇到这个问题,选择(成功!)使用了你的解决方案,只是稍微有些不同:我使用了uuid.getnode()来找到我的系统的uuid。因此,我正在测试是否uuid.getnode()== 12345678901(实际上是另一个数字),而不是你使用的os.environ测试。我无法找到文档来证明os.environ ['COMPUTERNAME']在每台计算机上都是唯一的。 - Joe Golton
os.environ['COMPUTERNAME']在Amazon AWS Ubuntu上无法工作。我收到了一个KeyError错误。 - nu everest
当使用UUID时,这个解决方案对我来说已经被证明是最好和最简单的。它不需要大量复杂和过度模块化的拼凑。在生产环境中,您仍然需要将数据库密码和SECRET_KEY放置在一个位于版本控制之外的单独文件中。 - nu everest
os.environ['COMPUTERNAME'] 在 PythonAnywhere 上不起作用,会出现 KeyError。 - nbeuchat

16
TL;DR: 在任何settings/<purpose>.py文件中导入settings/base.py之前,修改os.environment,这将大大简化事情。
思考所有这些交织在一起的文件就让我头疼。组合、导入(有时是有条件的)、覆盖、修补已经设置的内容以防DEBUG设置后来发生变化。真是噩梦!
多年来,我尝试了各种不同的解决方案。它们都“有点”可行,但管理起来非常痛苦。我们最开始只有一个settings.py文件。现在我们需要文档才能正确地将它们正确组合在一起!
我希望下面的解决方案终于能够达到(我的)理想状态。

让我们回顾一下目标(一些共同的,一些是我的)

  1. 保持秘密的秘密 - 不要将它们存储在仓库中!

  2. 通过环境设置设置/读取密钥和密码,遵循12 factor风格

  3. 具有明智的回退默认值。理想情况下,对于本地开发,您除了默认值之外什么都不需要。

  4. ...但尽量保持默认设置的安全性。在本地缺少设置覆盖比记住调整适用于生产的默认设置更好。

  5. 有能力以可以影响其他设置的方式切换DEBUG的开/关状态(例如使用压缩的javascript或不使用)。

  6. 仅基于DJANGO_SETTINGS_MODULE切换目的设置,没有其他的。

  7. ...但允许通过环境设置进行进一步参数化,例如DATABASE_URL

  8. ...还允许它们使用不同的目的设置并在本地并行运行,例如在本地开发人员机器上设置为生产设置,以访问生产数据库或测试压缩样式表。

  9. 如果未明确设置环境变量,则失败(至少需要一个空值),特别是在生产中,例如EMAIL_HOST_PASSWORD

  10. django-admin startproject期间响应于默认的DJANGO_SETTINGS_MODULE设置。

  11. 将条件语句最小化,如果条件是目的环境类型(例如,为生产设置日志文件及其旋转),则在关联的目的设置文件中覆盖设置。

不要这样做

  1. 不要让Django从文件中读取DJANGO_SETTINGS_MODULE设置。
    哎呀!考虑一下这是多么的元啊。如果您需要读取文件(例如docker env),请在启动django进程之前将其读入环境中。

  2. 不要在项目/应用程序代码中覆盖DJANGO_SETTINGS_MODULE,例如基于主机名或进程名称进行覆盖。
    如果您懒得设置环境变量(例如对于setup.py test),请在运行项目代码之前的工具中设置。

  3. 避免使用魔法和补丁来读取Django设置,预处理设置但不干扰后续过程。

  4. 不要使用基于复杂逻辑的胡言乱语。配置应该是固定的和具体化的,不应该在运行时被计算。提供一个后备默认值就足够了。
    你真的想要调试吗?为什么在本地你有正确的设置,但在生产环境的远程服务器上有些机器计算出来的结果却不同呢?哦!单元测试?针对设置?认真的吗?

解决方案

我的策略包括使用 django-environini格式文件, 为本地开发提供os.environment默认设置,一些最小和简短的settings /<purpose>.py文件,在从INI文件中设置os.environment之后, 导入import settings/base.py。这为我们提供了一种设置注入方式。

此处的诀窍是在导入settings/base.py之前修改os.environment

要查看完整示例,请转到库:https://github.com/wooyek/django-settings-strategy

.
│   manage.py
├───data
└───website
    ├───settings
    │   │   __init__.py   <-- imports local for compatibility
    │   │   base.py       <-- almost all the settings, reads from proces environment 
    │   │   local.py      <-- a few modifications for local development
    │   │   production.py <-- ideally is empty and everything is in base 
    │   │   testing.py    <-- mimics production with a reasonable exeptions
    │   │   .env          <-- for local use, not kept in repo
    │   __init__.py
    │   urls.py
    │   wsgi.py

settings/.env

这是一个用于本地开发的默认设置文件,它包含了大多数必要的环境变量。如果某些变量在本地开发中不需要,请将其设置为空值。我们在此提供默认值,而不是在 settings/base.py 中提供默认值,以便在任何其他机器上缺少这些变量时出错。

settings/local.py

这里的操作是从 settings/.env 加载环境变量,然后从 settings/base.py 导入通用设置。之后,我们可以覆盖一些设置以方便本地开发。

import logging
import environ

logging.debug("Settings loading: %s" % __file__)

# This will read missing environment variables from a file
# We wan to do this before loading a base settings as they may depend on environment
environ.Env.read_env(DEBUG='True')

from .base import *

ALLOWED_HOSTS += [
    '127.0.0.1',
    'localhost',
    '.example.com',
    'vagrant',
    ]

# https://docs.djangoproject.com/en/1.6/topics/email/#console-backend
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
# EMAIL_BACKEND = 'django.core.mail.backends.dummy.EmailBackend'

LOGGING['handlers']['mail_admins']['email_backend'] = 'django.core.mail.backends.dummy.EmailBackend'

# Sync task testing
# http://docs.celeryproject.org/en/2.5/configuration.html?highlight=celery_always_eager#celery-always-eager

CELERY_ALWAYS_EAGER = True
CELERY_EAGER_PROPAGATES_EXCEPTIONS = True

设置/production.py

在生产环境中,我们不应该期望有一个环境文件,但如果我们要测试某些内容,拥有一个环境文件会更容易。无论如何,让我们提供一些默认值,这样settings/base.py可以相应地做出响应。

environ.Env.read_env(Path(__file__) / "production.env", DEBUG='False', ASSETS_DEBUG='False')
from .base import *

这里最重要的是 DEBUGASSETS_DEBUG 覆盖,它们仅在环境和文件中缺失时才会应用于 python 的 os.environ
这些将成为我们的生产默认设置,不需要将它们放入环境或文件中,但如果需要,可以进行覆盖。很棒!

settings/base.py

这些是您基本的 Django 设置,其中包含一些条件语句和许多从环境中读取的内容。几乎所有东西都在这里,保持所有目的环境一致且尽可能相似。
主要区别如下(希望这些都很容易理解):
import environ

# https://github.com/joke2k/django-environ
env = environ.Env()

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

# Where BASE_DIR is a django source root, ROOT_DIR is a whole project root
# It may differ BASE_DIR for eg. when your django project code is in `src` folder
# This may help to separate python modules and *django apps* from other stuff
# like documentation, fixtures, docker settings
ROOT_DIR = BASE_DIR

# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = env('SECRET_KEY')

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = env('DEBUG', default=False)

INTERNAL_IPS = [
    '127.0.0.1',
]

ALLOWED_HOSTS = []

if 'ALLOWED_HOSTS' in os.environ:
    hosts = os.environ['ALLOWED_HOSTS'].split(" ")
    BASE_URL = "https://" + hosts[0]
    for host in hosts:
        host = host.strip()
        if host:
            ALLOWED_HOSTS.append(host)

SECURE_SSL_REDIRECT = env.bool('SECURE_SSL_REDIRECT', default=False)

# Database
# https://docs.djangoproject.com/en/1.11/ref/settings/#databases

if "DATABASE_URL" in os.environ:  # pragma: no cover
    # Enable database config through environment
    DATABASES = {
        # Raises ImproperlyConfigured exception if DATABASE_URL not in os.environ
        'default': env.db(),
    }

    # Make sure we use have all settings we need
    # DATABASES['default']['ENGINE'] = 'django.contrib.gis.db.backends.postgis'
    DATABASES['default']['TEST'] = {'NAME': os.environ.get("DATABASE_TEST_NAME", None)}
    DATABASES['default']['OPTIONS'] = {
        'options': '-c search_path=gis,public,pg_catalog',
        'sslmode': 'require',
    }
else:
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.sqlite3',
            # 'ENGINE': 'django.contrib.gis.db.backends.spatialite',
            'NAME': os.path.join(ROOT_DIR, 'data', 'db.dev.sqlite3'),
            'TEST': {
                'NAME': os.path.join(ROOT_DIR, 'data', 'db.test.sqlite3'),
            }
        }
    }

STATIC_ROOT = os.path.join(ROOT_DIR, 'static')

# django-assets
# http://django-assets.readthedocs.org/en/latest/settings.html

ASSETS_LOAD_PATH = STATIC_ROOT
ASSETS_ROOT = os.path.join(ROOT_DIR, 'assets', "compressed")
ASSETS_DEBUG = env('ASSETS_DEBUG', default=DEBUG)  # Disable when testing compressed file in DEBUG mode
if ASSETS_DEBUG:
    ASSETS_URL = STATIC_URL
    ASSETS_MANIFEST = "json:{}".format(os.path.join(ASSETS_ROOT, "manifest.json"))
else:
    ASSETS_URL = STATIC_URL + "assets/compressed/"
    ASSETS_MANIFEST = "json:{}".format(os.path.join(STATIC_ROOT, 'assets', "compressed", "manifest.json"))
ASSETS_AUTO_BUILD = ASSETS_DEBUG
ASSETS_MODULES = ('website.assets',)

最后一部分展示了这里的强大之处。ASSETS_DEBUG有一个合理的默认值,可以在settings/production.py中被覆盖,甚至可以被环境设置所覆盖!太好了!
实际上,我们有一个重要性的混合层次结构:
1. settings/.py - 根据目的设置默认值,不存储机密信息 2. settings/base.py - 大部分由环境控制 3. 进程环境设置 - 12因素宝宝! 4. settings/.env - 用于简便启动的本地默认值

嗨,Janusz... 那么在.env文件中会放置所有的API密钥、认证密钥和密码等吗?就像TWILLIO_API = "abc123"一样吗?还是TWILLIO_API = env("TWILLIO_API")? - dbinott
是的,但这只是环境设置的备选方案。这个文件在开发中很方便,但不会保存在仓库中或推送到生产环境,在那里你应该严格使用环境设置或平台等效设置,以便为服务器进程设置环境设置。 - Janusz Skonieczny
如何定义生产环境设置?例如,当我明确将我的DJANGO_SETTINGS_MODULE定义为website/settings/production时,__init__文件仍会加载local.py设置。我该如何避免它,或者我做错了什么? - arnon cohen

14

我使用 settings_local.py 和 settings_production.py,尝试了几种方案后,发现只需使用两个设置文件即感觉轻松快捷,不需要复杂的解决方案。

当您在 Django 项目中使用 mod_python/mod_wsgi 时,您需要指向您的设置文件。如果在本地服务器上指向 app/settings_local.py,在生产服务器上指向 app/settings_production.py,则会变得轻松。只需编辑相应的设置文件并重新启动服务器(Django 开发服务器将自动重启)。


2
本地开发服务器怎么办?有没有一种方法可以告诉Django Web服务器(使用python manage.py runserver运行),要使用哪个设置文件? - akv
3
如果你在runserver命令的结尾加上--settings=[模块名称](不要加上.py扩展名),你就可以指定要使用哪个设置文件。如果你打算这样做,最好先创建一个带有开发设置的shell脚本/批处理文件。相信我,这样做会让你的手指感谢你。 - T. Stone
这是我使用的解决方案。将设置文件修改以用于生产或开发会很混乱。 - George Godik
4
我认为在开发中使用settings.py更好,因为您不必一直指定它。 - Andre Bossard
我假设这种方法需要通过代理django.conf.settings导入设置模块吗?否则,在推送实时环境时,您需要编辑导入声明,以指向正确的设置文件。 - Will

7
我使用 django-split-settings 来管理我的配置。
它是默认设置的替代品。它简单易用,但也可以进行配置。不需要重构现有的设置。
以下是一个小例子(文件 example/settings/__init__.py):
from split_settings.tools import optional, include
import os

if os.environ['DJANGO_SETTINGS_MODULE'] == 'example.settings':
    include(
        'components/default.py',
        'components/database.py',
        # This file may be missing:
        optional('local_settings.py'),

        scope=globals()
    )

就这样。

更新

我写了一篇关于使用 django-split-sttings 管理 django 设置的博客文章。看一看吧!


1
我尝试过了,但当我尝试运行我的Django单元测试时遇到了问题。我就是无法弄清楚如何指定要读取哪个设置文件。 - abbood
我已经为您创建了一个Gist: https://gist.github.com/sobolevn/006c734f0520439a4b6c16891d65406c - sobolevn
我在我的代码中得到了一些类似于这样的东西,因此我检查settings.DEBUG标志以确定是否要导入一些东西.. 在django单元测试中,该标志始终设置为false(见此处),所以我的解决方法是在每个测试中覆盖它们,就像这样 - abbood
这里还有一个问题:我的 uwsgi.ini 文件在开发和生产环境中有不同的设置.. 有什么办法可以让它从我的设置文件中获取值吗? - abbood
抱歉,我不明白设置的情况。您可以提出一个更详细的问题,我会尽力帮助您。 - sobolevn

7

请记住,settings.py是一个实时的代码文件。假设您在生产环境中没有设置DEBUG(这是最佳实践),您可以执行以下操作:

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

这很基础,但理论上,你可以根据DEBUG的值或任何其他变量或代码检查来提高复杂度。


6
大多数解决方案的问题在于,您要么在通用设置之前应用本地设置,要么在通用设置之后应用本地设置。因此,无法同时覆盖以下内容:
- env-specific设置定义了memcached池的地址,并且在主要设置文件中使用此值来配置缓存后端。 - env-specific设置添加或删除默认应用程序/中间件。
可以使用“ini”样式的配置文件和ConfigParser类来实现一种解决方案。它支持多个文件、惰性字符串插值、默认值和许多其他好处。加载一些文件后,可以加载更多文件,如果有任何值覆盖则会覆盖以前的值。根据机器地址、环境变量甚至是先前加载的配置文件中的值,加载一个或多个配置文件,然后只需使用解析出的值填充设置。一个成功使用的策略是:
- 加载默认的defaults.ini文件。 - 检查机器名称,并加载所有与反向FQDN匹配的文件,从最短的匹配到最长的匹配(因此,我加载了net.ini,然后是net.domain.ini,然后是net.domain.webserver01.ini,每个文件都可能覆盖以前的值)。这也适用于开发人员的机器,因此每个人都可以为本地开发设置其首选数据库驱动程序等。 - 检查是否声明了“群集名称”,如果是,则加载cluster.cluster_name.ini,其中可以定义数据库和缓存IP等内容。
使用此方法可以实现的示例是,在每个环境中定义一个“子域”值,然后在默认设置中使用它(如hostname: %(subdomain).whatever.net),以定义django所需的所有必要主机名和cookie信息。这是我能够达到的最DRY状态,大多数(现有的)文件只有3或4个设置。除此之外,我还需要管理客户配置,因此存在另一组配置文件(例如数据库名称、用户和密码、分配的子域等),每个客户端都有一个或多个。您可以根据需要将其扩展到任何规模,只需在配置文件中放置要针对每个环境配置的键,并且一旦需要新配置,就将先前的值放入默认配置中,并在必要时进行覆盖。该系统已被证明是可靠的,并且与版本控制很好地配合使用。它已经长时间用于管理两个单独的应用程序集群(每台机器有15个或更多个django站点实例),超过50个客户端,其中集群的大小和成员取决于系统管理员的心情...

1
你有没有一个例子,可以展示如何将ini文件中的设置加载到Django的设置中? - kaleissin
请参阅 http://docs.python.org/2/library/configparser.html。您可以使用 config = ConfigParser.ConfigParser() 加载解析器,然后使用 config.read(array_of_filenames) 读取文件并使用 config.get(section, option) 获取值。因此,首先加载配置文件,然后使用它来读取设置的值。 - rewritten

5

我也在使用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

也许这个可以帮助你。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接