如何在Django中管理本地vs生产设置?

时间:2009-10-26 18:00:27

标签: python django deployment

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

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

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

21 个答案:

答案 0 :(得分:275)

Two Scoops of Django: Best Practices for Django 1.5建议对您的设置文件使用版本控制,并将文件存储在单独的目录中:

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上提出了a sample project layout template

答案 1 :(得分:124)

settings.py

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

您可以覆盖local_settings.py中所需的内容;它应该远离你的版本控制。但既然你提到复制,我猜你没有使用;)

答案 2 :(得分:66)

使用此布局代替settings.py

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

common.py是您的大多数配置存在的地方。

prod.py从普通内容中导入所有内容,并覆盖需要覆盖的内容:

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特定的内容放在prod.py中,特定于dev的内容放在dev.py中。这很简单。
  4. 您可以覆盖common.pyprod.py中的dev.py内容,您可以覆盖__init__.py中的任何内容。
  5. 这是简单的python。没有重新进口黑客。

答案 3 :(得分:20)

我使用了Harper Shelby发布的“if DEBUG”设置风格的略微修改版本。显然取决于环境(win / linux / etc.),代码可能需要稍微调整一下。

我过去使用“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设置,同时也不是设置的麻烦(我没有使用5x设置文件方法)。

答案 4 :(得分:14)

我使用了settings_local.py和settings_production.py。在尝试了几个选项后,我发现只需简单地让两个设置文件感觉简单快捷,就可以轻松地将时间浪费在复杂的解决方案上。

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

答案 5 :(得分: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()
    )

就是这样。

更新

我写了blog post关于使用django管理django-split-sttings设置的问题。看看吧!

答案 6 :(得分:6)

大多数这些解决方案的问题在于,您可以在普通设置之前应用,或者在之后

所以不可能覆盖像

这样的东西
  • 特定于env的设置定义了memcached池的地址,在主设置文件中,此值用于配置缓存后端
  • 特定环境设置将应用/中间件添加或删除为默认设置

同时。

使用ConfigParser类的“ini”式配置文件可以实现一个解决方案。它支持多个文件,惰性字符串插值,默认值和许多其他好东西。 一旦加载了许多文件,就可以加载更多的文件,如果有的话,它们的值将覆盖以前的文件。

您加载一个或多个配置文件,具体取决于计算机地址,环境变量甚至以前加载的配置文件中的值。然后,您只需使用已解析的值来填充设置。

我成功使用的一个策略是:

  • 加载默认的defaults.ini文件
  • 检查机器名称,并加载与反向FQDN匹配的所有文件,从最短匹配到最长匹配(因此,我加载net.ini,然后加载net.domain.ini,然后加载net.domain.webserver01.ini ,每个可能覆盖前一个的值)。此帐户也适用于开发人员的计算机,因此每个人都可以为本地开发设置其首选数据库驱动程序等
  • 检查是否声明了“群集名称”,并且在这种情况下加载cluster.cluster_name.ini,它可以定义数据库和缓存IP等内容

作为您可以通过此实现的一个示例,您可以定义“subdomain”值per-env,然后在默认设置(如hostname: %(subdomain).whatever.net)中使用它来定义所有必需的主机名和cookie django需要工作的东西。

这就像我可以获得的干,大多数(现有)文件只有3或4个设置。除此之外,我必须管理客户配置,因此存在一组额外的配置文件(包括数据库名称,用户和密码,分配的子域等),每个客户一个或多个。

可以根据需要将其扩展为低或高,只需在配置文件中输入要为每个环境配置的密钥,并且一旦需要新配置,将前一个值放在默认配置中,并在必要时覆盖它。

该系统经证实可靠,适用于版本控制。它已被用于长时间管理两个独立的应用程序集群(每台机器的15个或更多单独的django站点实例),有超过50个客户,其中集群根据系统管理员的情绪改变大小和成员。

答案 7 :(得分:5)

TL; DR:诀窍是在os.environment中导入settings/base.py之前修改settings/<purpose>.py,这将大大简化事情。

考虑所有这些交织在一起的文件让我很头疼。 组合,导入(有时是有条件的),覆盖,修补已在DEBUG设置的情况下已设置的内容稍后更改。 多么噩梦!

多年来,我经历了各种不同的解决方案。他们都有点工作,但管理起来却很痛苦。 WTF!我们真的需要一切麻烦吗?我们从一个settings.py文件开始。 现在我们需要一个文档才能正确地将所有这些组合在一起!

我希望我终于通过下面的解决方案点击(我的)最佳位置。

让我们回顾一下目标(一些常见的,一些我的)

  1. 保密秘密 - 不要将它们存放在回购中。

  2. 通过环境设置12 factor style设置/读取密钥和密钥。

  3. 有合理的后备默认值。理想情况下,对于本地开发,除了默认值之外,您不需要任何其他内容。

  4. ...但尝试保持默认生产安全。最好错过本地设置覆盖, 而不必记住调整生产安全的默认设置。

  5. 能够以对其他设置产生影响的方式打开/关闭DEBUG(例如,使用压缩的javascript)。

  6. 在目的设置(如本地/测试/暂存/制作)之间切换应仅基于DJANGO_SETTINGS_MODULE,仅此而已。

  7. ...但允许通过DATABASE_URL等环境设置进一步参数化。

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

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

  10. 响应django-admin startproject

    期间在manage.py中设置的默认DJANGO_SETTINGS_MODULE
  11. 将条件保持在最低限度,如果条件是 目的环境类型(例如,对于生产集日志文件及其旋转),则覆盖相关目的设置中的设置文件。

  12. 不要

    1. 不要让django将DJANGO_SETTINGS_MODULE设置形成文件。
      啊!想想这是多么美好。如果你需要一个文件(如docker env)在开始django过程之前将其读入环境。

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

    3. 避免魔术和修补django如何读取它的设置,预处理设置但不会干扰。

    4. 没有复杂的基于逻辑的废话。配置应该是固定的,具体化不是动态计算的。 提供后备默认值就足够了。
      你真的想调试吗,为什么本地你有正确的设置,但在远程服务器上生产, 在一百台机器上,计算出不同的东西?哦!单元测试?对于设置?真的吗?

    5. 解决方案

      我的策略包括与ini样式文件一起使用的优秀django-environ, 提供os.environment本地开发的默认值,一些最小和短settings/<purpose>.py个文件 import settings/base.py AFTER os.environment是从INI文件设置的。这有效地为我们提供了一种注入设置。

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

      要查看完整示例,请执行repo:https://github.com/wooyek/django-settings-strategy

      .
      │   manage.py
      ├───data
      └───website
          ├───settings
          │   │   __init__.py   <-- imports local for compatybility
          │   │   base.py       <-- almost all the settings, reads from proces environment 
          │   │   local.py      <-- a few modifications for local development
          │   │   production.py <-- ideally is empy 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
      

      设置/ .ENV

      本地开发的默认值。一个秘密文件,主要用于设置所需的环境变量。 如果在本地开发中不需要它们,则将它们设置为空值。 我们在此提供默认设置,而不是settings/base.py中的默认设置,如果环境中缺少任何其他计算机,则会失败。

      设置/ 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

      这些将是我们的生产默认值,无需将它们放在环境或文件中,但如果需要,可以覆盖它们。整齐!

      设置/ 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 - 轻松启动的本地默认值

答案 8 :(得分:4)

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

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

非常基础,但理论上,你可以根据DEBUG的值 - 或者你想要使用的任何其他变量或代码检查来达到任何复杂程度。

答案 9 :(得分:4)

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

也许这样的事情可以帮到你。

答案 10 :(得分:3)

对于我的大多数项目,我使用以下模式:

  1. 创建settings_base.py,其中我存储所有环境通用的设置
  2. 每当我需要使用具有特定要求的新环境时,我都会创建新的设置文件(例如.settings_local.py),该文件继承了settings_base.py的内容并覆盖/添加了正确的设置变量(from settings_base import *
  3. (要使用自定义设置文件运行manage.py,只需使用--settings命令选项:manage.py <command> --settings=settings_you_wish_to_use.py

答案 11 :(得分:3)

我使用了上面提到的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文件,可以动态加载。

答案 12 :(得分:3)

我对这个问题的解决方案也有点混合了这里已经说过的一些解决方案:

  • 我保留了一个名为local_settings.py的文件,该文件的内容为USING_LOCAL = True,而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文件,这意味着我不能盲目地复制所有文件,但这是我可以忍受的。

答案 13 :(得分:3)

还有Django Classy设置。我个人非常喜欢它。它由Django IRC上最活跃的人之一构建。您可以使用环境变量进行设置。

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

答案 14 :(得分:2)

要在不同环境中使用不同的settings配置,请创建不同的设置文件。在您的部署脚本中,使用--settings=<my-settings.py>参数启动服务器,通过该参数,您可以在不同的环境中使用不同的设置

使用此方法的好处

  1. 您的设置将根据每个环境进行模块化

  2. 您可以在master_settings.py中导入包含基本配置的environmnet_configuration.py,并覆盖您要在该环境中更改的值。

  3. 如果您拥有庞大的团队,每个开发人员可能拥有自己的local_settings.py,他们可以将其添加到代码存储库中,而不会有任何修改服务器配置的风险。如果您使用 git ,则可以将这些本地设置添加到.gitnore;如果 Mercurial 用于版本控制,则可以将.hginore添加到.py或任何其他)。这样,本地设置甚至不会成为保持干净的实际代码库的一部分。

答案 15 :(得分:1)

我在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)

我发现将设置文件分成两个单独的文件更容易,而不是在设置文件中执行大量的ifs。

答案 16 :(得分:1)

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

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

此外,它还将从github中删除settings.py文件,这是我见过许多新手所做的大错。

答案 17 :(得分:1)

1 - 在您的应用内创建一个新文件夹,并为其命名设置。

2 - 现在在其中创建一个新的 init .py文件并在其中写入

    from .base import *

    try:

        from .local import *

    except:

        pass

     try:

         from .production import *

     except:

         pass

3 - 在设置文件夹名称local.py和production.py以及base.py

中创建三个新文件

4 - 在base.py里面复制以前的settings.p文件夹的所有内容,并用不同的东西重命名,比如说old_settings.py

5 - 在base.py中更改您的BASE_DIR路径以指向您的新设置路径

旧路径 - &gt; BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath( file )))

新途径 - &gt; BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath( file )))

现在通过这种方式,项目目录可以结构化,并且可以在生产和本地开发中进行管理。

答案 18 :(得分:0)

制作settings.py的多个版本是12 Factor App methodology的反模式。 改用python-decoupledjango-environ

答案 19 :(得分:0)

我认为@T建议最好的解决方案。斯通,但我不知道为什么不在Django中使用DEBUG标志。我为我的网站编写以下代码:

if DEBUG:
    from .local_settings import *

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

答案 20 :(得分:-3)

我发现这里的回复非常有帮助。 (这是否已经更明确地解决了?最后一次回复是一年前的事了。)在考虑了列出的所有方法之后,我想出了一个我没有在这里列出的解决方案。

我的标准是:

  • Everything 应该在源代码管理中。我不喜欢四处闲聊。
  • 理想情况下,将设置保存在一个文件中。如果我不正确的话,我会忘记这些事情:)
  • 无需手动编辑即可部署。应该能够使用单个结构命令进行测试/推送/部署。
  • 避免将开发设置泄漏到生产环境中。
  • 尽可能接近“标准”(*咳嗽*)Django布局。

我认为切换主机有一定意义,但后来认为真正的问题是不同的环境的不同设置,并且有一个aha时刻。我将此代码放在我的settings.py文件的 end 中:

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总是让它变得如此模糊以至于你可以设置环境变量。)

使用这种方法,开发设置都在一个(标准)位置,并根据需要简单地覆盖生产设置。任何涉及开发设置的问题应该是完全安全的,可以在不影响生产的情况下进行源代码管理。