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

2025-01-09 08:46:00
admin
原创
24
摘要:问题描述:处理本地开发和生产服务器设置的推荐方法是什么?其中一些(如常量等)可以在两者中更改/访问,但其中一些(如静态文件的路径)需要保持不同,因此每次部署新代码时都不应覆盖它们。目前,我正在将所有常量添加到settings.py。但每次我在本地更改某些常量时,我​​都必须将其复制到生产服务器并编辑文件以进行...

问题描述:

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

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

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


解决方案 1:

《Two Scoops of Django: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.py具有production.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 上给出了示例项目布局模板。

解决方案 2:

settings.py

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

您可以覆盖所需的内容local_settings.py;这样它就不会受到版本控制。但既然您提到了复制,我猜您没有使用 ;)

解决方案 3:

不要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.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..."

我喜欢这个解决方案的原因是:

  1. 所有内容都在你的版本控制系统中,除了机密

  2. 大多数配置都在一个地方:common.py

  3. 产品专用的东西放进去prod.py,开发专用的东西放进去dev.py。很简单。

  4. 您可以覆盖或common.py中的内容,也可以覆盖 中的任何内容。prod.py`dev.py`__init__.py

  5. 这是简单易懂的 Python。无需重新导入。

解决方案 4:

我使用了 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 设置文件方法)。

解决方案 5:

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


光是想想这些相互交织的文件就让我头疼。合并、导入(有时是有条件的)、覆盖、修补已经设置的内容,以防DEBUG设置稍后发生变化。真是一场噩梦!

这些年来,我尝试过各种不同的解决方案。它们都有些作用,但管理起来非常麻烦。哇!我们真的需要这么麻烦吗?我们从一个settings.py文件开始。现在我们需要一个文档,以便以正确的顺序正确地将所有这些文件组合在一起!

我希望我最终能通过下面的解决方案找到(我)的最佳解决方案。

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

  1. 保守秘密——不要将它们存储在仓库中!

  2. 通过环境设置设置/读取密钥和秘密,12 因素风格。

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

  4. …但尽量保持默认生产安全。最好在本地忽略设置覆盖,而不是必须记住调整默认生产安全设置。

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

  6. 在本地/测试/登台/生产等目的设置之间切换应该仅基于DJANGO_SETTINGS_MODULE,仅此而已。

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

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

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

  10. 在django-admin startproject期间响应DJANGO_SETTINGS_MODULEmanage.py 中的默认设置

  11. 将条件保持在最低限度,如果条件是有目的的环境类型(例如,用于生产集日志文件及其轮换),则覆盖相关有目的的设置文件中的设置。

不要

  1. 不要让 django 从文件中读取 DJANGO_SETTINGS_MODULE 设置。

哎呀!想想这是多么的元数据。如果您需要一个文件(如 docker env),请在启动 django 进程之前将其读入环境中。

  1. 不要在项目/应用代码中覆盖 DJANGO_SETTINGS_MODULE,例如基于主机名或进程名。

如果您懒得设置环境变量(例如 for setup.py test),请在运行项目代码之前在工具中执行此操作。

  1. 避免对 django 读取其设置的方式进行魔法和修补,预处理设置但之后不要干扰。

  2. 没有基于复杂逻辑的废话。配置应该是固定的和具体化的,而不是动态计算的。提供后备默认值在这里就足够有逻辑了。

你真的想调试吗,为什么你在本地有正确的设置集,但在远程服务器上的生产中,在一百台机器中的一台上,计算结果却不同?哦!单元测试?对于设置?真的吗?

解决方案

我的策略包括使用出色的django-environini和样式文件,os.environment为本地开发提供默认值,以及一些最小且简短的settings/<purpose>.py文件,这些文件
在文件中设置了AFTER import settings/base.py 这有效地为我们提供了一种设置注入。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 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

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

设置/生产.py

对于生产,我们不应该期望有环境文件,但如果我们正在测试某些东西,那么拥有一个环境文件会更容易。但无论如何,我们都会提供一些内联默认值,以便settings/base.py可以做出相应的响应。

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

这里主要关注的点是DEBUG和覆盖,仅当它们在环境和文件中缺失时,ASSETS_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 - 方便启动的本地默认值

解决方案 6:

我使用 settings_local.py 和 settings_production.py。尝试了几种方案后,我发现,如果只使用两个设置文件,那么解决复杂问题很容易浪费时间,而解决复杂问题则容易让人感觉轻松快捷。

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

解决方案 7:

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

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

非常基础,但理论上,您可以仅基于 DEBUG 的值(或您想要使用的任何其他变量或代码检查)达到任何复杂程度。

解决方案 8:

我在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`django-split-sttings`

解决方案 9:

大多数这些解决方案的问题在于,您要么在通用设置之前应用本地设置,要么在通用设置之后应用本地设置。

因此不可能覆盖以下内容

  • 环境特定的设置定义了 memcached 池的地址,在主设置文件中,此值用于配置缓存后端

  • 环境特定的设置将应用程序/中间件添加或删除为默认设置

同时。

可以使用 ConfigParser 类来实现“ini”样式的配置文件。它支持多个文件、惰性字符串插值、默认值和许多其他优点。加载多个文件后,可以加载更多文件,并且它们的值将覆盖先前的值(如果有)。

您可以根据机器地址、环境变量甚至先前加载的配置文件中的值来加载一个或多个配置文件。然后您只需使用解析的值来填充设置。

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

  • 加载默认defaults.ini文件

  • 检查机器名称,并加载所有与反向 FQDN 匹配的文件,从最短匹配到最长匹配(因此,我加载了net.ini,然后net.domain.ini,然后net.domain.webserver01.ini,每个都可能覆盖前一个的值)。此帐户也适用于开发人员的机器,因此每台机器都可以为本地开发设置其首选的数据库驱动程序等。

  • 检查是否声明了“集群名称”,如果是,则加载cluster.cluster_name.ini,它可以定义数据库和缓存 IP 等内容

作为您可以通过此方法实现的目标的一个例子,您可以为每个环境定义一个“子域”值,然后在默认设置(as hostname: %(subdomain).whatever.net)中使用该值来定义 django 工作所需的所有必要主机名和 cookie。

这是我所能想到的最 DRY 方式,大多数(现有)文件只有 3 或 4 个设置。除此之外,我还必须管理客户配置,因此存在一组额外的配置文件(包含数据库名称、用户和密码、分配的子域等内容),每个客户有一个或多个。

您可以根据需要将其缩放到尽可能低或尽可能高,只需在配置文件中放入您想要为每个环境配置的键,一旦需要新的配置,就将先前的值放入默认配置中,并在必要时覆盖它。

该系统已被证明是可靠的,并且与版本控制配合良好。它已长期用于管理两个独立的应用程序集群(每台机器有 15 个或更多独立的 django 站点实例),拥有超过 50 个客户,其中集群的大小和成员会根据系统管理员的心情而改变...

解决方案 10:

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

  1. 创建 settings_base.py,用于存储所有环境通用的设置

  2. 每当我需要使用具有特定要求的新环境时,我都会创建新的设置文件(例如 settings_local.py),它继承 settings_base.py 的内容并覆盖/添加适当的设置变量(from settings_base import *

(要使用自定义设置文件运行 manage.py,只需使用 --settings 命令选项manage.py <command> --settings=settings_you_wish_to_use.py:)

解决方案 11:

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

也许这样的事情会对你有帮助。

解决方案 12:

1 - 在您的应用程序内创建一个新文件夹并将设置命名为它。

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

from .base import *

try:
    from .local import *
except:
    pass

try:
    from .production import *
except:
    pass

3 - 在设置文件夹名称local.pyproduction.py和中创建三个新文件base.py

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

5 - 在 base.py 中,将 BASE_DIR 路径更改为指向新的设置路径

旧路径->
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

新路径 ->
BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

这样,项目目录就可以结构化,并可以在生产和本地开发之间进行管理。

解决方案 13:

我对该问题的解决方案也混合了这里已经提到的一些解决方案:

  • 我保存了一个名为的文件,其中包含dev 和prod 中local_settings.py的内容USING_LOCAL = True`USING_LOCAL = False`

  • 我导入settings.py该文件以获取USING_LOCAL设置

然后我把所有与环境相关的设置都建立在这一点上:

DEBUG = USING_LOCAL
if USING_LOCAL:
    # dev database settings
else:
    # prod database settings

我更喜欢这样,而不是需要维护两个单独的 settings.py 文件,因为我可以更轻松地将设置结构化到单个文件中,而不是将它们分散到多个文件中。这样,当我更新设置时,我不会忘记为两个环境执行此操作。

当然,每种方法都有缺点,这个也不例外。这里的问题是,local_settings.py每当我将更改推送到生产中时,我都无法覆盖文件,这意味着我不能盲目地复制所有文件,但我可以忍受这一点。

解决方案 14:

我使用了上面 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.
You'll have to run django-admin.py, passing it your settings module.
(If the file local_settings.py does indeed exist, it's causing an ImportError somehow.)
" % (computername, __file__))
  sys.exit(1)

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

基本上,在每台计算机(开发或生产)上,我都有动态加载的适当的 hostname_settings.py 文件。

解决方案 15:

还有 Django Classy Settings。我个人非常喜欢它。它是由 Django IRC 上最活跃的人之一创建的。您可以使用环境变量来设置事物。

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

解决方案 16:

制作 settings.py 的多个版本是12 Factor App 方法的反模式。请改用python-decouple或django-environ。

解决方案 17:

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

使用此方法的好处

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

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

  3. 如果您的团队规模庞大,那么每个开发人员可能都有自己的代码库local_settings.py,他们可以将这些代码库添加到代码库中,而无需承担修改服务器配置的风险。如果您使用 git 或 Mercurial 进行版本控制(或任何其他),则可以添加这些本地设置。.gitnore这样本地设置甚至不会成为实际代码库的一部分,从而保持代码库的整洁。.hginore

解决方案 18:

我的设置如下

settings/
     |
     |- base.py
     |- dev.py
     |- prod.py  

我们有 3 个环境

  • 开发

  • 分期

  • 生产

现在显然,暂存和生产应该具有尽可能相似的环境。所以我们保留prod.py了两者。

但有一种情况是我必须确定正在运行的服务器是否是生产服务器。@T. Stone 的回答帮助我写了如下检查。

from socket import gethostname, gethostbyname  
PROD_HOSTS = ["webserver1", "webserver2"]

DEBUG = False
ALLOWED_HOSTS = [gethostname(), gethostbyname(gethostname()),]


if any(host in PROD_HOSTS for host in ALLOWED_HOSTS):
    SESSION_COOKIE_SECURE = True
    CSRF_COOKIE_SECURE = True  

解决方案 19:

我在 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.
You'll have to run django-admin.py, passing it your settings module.
(If the file local_settings.py does indeed exist, it's causing an ImportError somehow.)
" % __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.
You'll have to run django-admin.py, passing it your settings module.
(If the file prod_settings.py does indeed exist, it's causing an ImportError somehow.)
" % __file__)
        sys.exit(1)

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

我发现将设置文件分成两个单独的文件比在设置文件中执行大量的 if 更容易。

解决方案 20:

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

这样您就可以在两个地方拥有不同的内容而不会出现任何问题。因此,您可以在服务器上配置一个独立版本的 settings.py,本地所做的任何更改都不会反映在服务器上,反之亦然。

此外,它还会从 github 中删除 settings.py 文件,这是一个大错误,我见过很多新手都这样做。

解决方案 21:

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

if DEBUG:
    from .local_settings import *

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

解决方案 22:

在 .env 文件中使用

DJANGO_SETTINGS_MODULE=config.settings.prod

这将默认采用 prod.py 文件的所有配置。并在具有以下配置时获取该值:

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.local")

当运行你的项目时,你会看到控制台内部它将指向 .env 文件中指示的新配置文件

Django version 4.2.4, using settings 'config.settings.prod'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

解决方案 23:

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

我的标准是:

  • 一切都应在源代码控制中。我不喜欢到处都是乱七八糟的东西。

  • 理想情况下,将设置保存在一个文件中。如果我不仔细看,我就会忘记事情 :)

  • 无需手动编辑即可部署。应该能够使用单个 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 总是使它变得如此模糊,以至于您可以设置环境变量。)

通过这种方法,开发设置全部集中在一个(标准)位置,只需在需要时覆盖生产设置即可。对开发设置的任何改动都应该完全安全地提交到源代码管理中,而不会对生产产生任何影响。

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   990  
  在项目管理领域,CDCP(Certified Data Center Professional)认证评审是一个至关重要的环节,它不仅验证了项目团队的专业能力,还直接关系到项目的成功与否。在这一评审过程中,沟通技巧的运用至关重要。有效的沟通不仅能够确保信息的准确传递,还能增强团队协作,提升评审效率。本文将深入探讨CDCP...
华为IPD流程   26  
  IPD(Integrated Product Development,集成产品开发)是一种以客户需求为核心、跨部门协同的产品开发模式,旨在通过高效的资源整合和流程优化,提升产品开发的成功率和市场竞争力。在IPD培训课程中,掌握关键成功因素是确保团队能够有效实施这一模式的核心。以下将从五个关键成功因素展开讨论,帮助企业和...
IPD项目流程图   27  
  华为IPD(Integrated Product Development,集成产品开发)流程是华为公司在其全球化进程中逐步构建和完善的一套高效产品开发管理体系。这一流程不仅帮助华为在技术创新和产品交付上实现了质的飞跃,还为其在全球市场中赢得了显著的竞争优势。IPD的核心在于通过跨部门协作、阶段性评审和市场需求驱动,确保...
华为IPD   26  
  华为作为全球领先的通信技术解决方案提供商,其成功的背后离不开一套成熟的管理体系——集成产品开发(IPD)。IPD不仅是一种产品开发流程,更是一种系统化的管理思想,它通过跨职能团队的协作、阶段评审机制和市场需求驱动的开发模式,帮助华为在全球市场中脱颖而出。从最初的国内市场到如今的全球化布局,华为的IPD体系在多个领域展现...
IPD管理流程   53  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用