首页 文章

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

提问于
浏览
258

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

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

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

20 回答

  • 1

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

  • 20

    settings.py

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

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

  • 14

    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
    )
    

    在文件生成设置文件_1774186中:

    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 .

  • 119

    而不是 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..."
    

    我喜欢这个解决方案是:

    • 除了秘密之外,一切都在您的版本控制系统中

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

    • 特定于Prod的东西进入 prod.py ,特定于dev的东西进入 dev.py . 这很简单 .

    • 您可以在 prod.pydev.py 中覆盖 common.py 中的内容,并且可以覆盖 __init__.py 中的任何内容 .

    • 这是简单的python . 没有重新进口黑客 .

  • 264

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

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

  • 1

    我在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-split-sttings 管理 django 的设置 . 看一看!

  • 1

    大多数这些解决方案的问题在于,您可以在常用设置之前应用本地设置,也可以在应用之后应用本地设置 .

    所以不可能覆盖像这样的东西

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

    • 特定于env的设置将应用程序/中间件添加或删除为默认值一

    同时 .

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

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

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

    • 加载默认 defaults.ini 文件

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

    • 检查是否有"cluster name"声明,在这种情况下加载 cluster.cluster_name.ini ,它可以定义数据库和缓存IP之类的东西

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

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

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

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

  • 3

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


    想到所有这些交织在一起的文件让我很头疼 . 组合,导入(有时是有条件的),覆盖,修补已经设置的情况 DEBUG 设置稍后更改 . 什么样的恶梦!

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

    我希望我终于用下面的解决方案击中(我的)最佳位置 .

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

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

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

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

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

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

    • 在目的设置(如本地/测试/暂存/ 生产环境 )之间切换应仅基于 DJANGO_SETTINGS_MODULE ,仅此而已 .

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

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

    • 如果未明确设置环境变量(最低要求空值),则失败,尤其是在 生产环境 中,例如 . EMAIL_HOST_PASSWORD .

    • django-admin startproject期间回复在manage.py中设置的默认 DJANGO_SETTINGS_MODULE

    • 如果条件是目的环境类型(例如,对于 生产环境 集日志文件及其旋转),则将条件保持为最小值,覆盖相关目的设置文件中的设置 .

    不要

    • 不要让django读取DJANGO_SETTINGS_MODULE设置表单文件 .
      啊!想想这是多么美好 . 如果您需要在启动django进程之前将文件(如docker env)读入环境中 .

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

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

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

    解决方案

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

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

    要查看完整的示例,请执行回购: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
    

    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
    

    settings / 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 中覆盖,甚至可以被环境设置覆盖!好极了!

    实际上,我们有一个重要的混合层次:

    • settings / .py - 根据目的设置默认值,不存储机密

    • settings / base.py - 主要由环境控制

    • 流程环境设置 - 12个因素宝贝!

    • settings / .env - 本地默认设置,便于启动

  • 2

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

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

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

  • 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
    

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

  • 5

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

    • 我保留了一个名为 local_settings.py 的文件,其中包含dev中的内容 USING_LOCAL = TrueUSING_LOCAL = False 中的内容

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

    然后,我将所有与环境相关的设置基于该设置:

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

    我更喜欢这个有两个单独的settings.py文件,我需要维护,因为我可以将我的设置结构化在一个文件中比将它们分布在多个文件中更容易 . 像这样,当我更新设置时,我没有忘了在两种环境中都这样做 .

    当然,每种方法都有其缺点,这一点也不例外 . 这里的问题是,每当我将更改推送到 生产环境 中时,我都无法覆盖 local_settings.py 文件,这意味着我可以使用't just copy all files blindly, but that' .

  • 3

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

    • 创建settings_base.py,其中我存储了所有环境通用的设置

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

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

  • 4

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

  • 3

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

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

  • 3

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

    Benefits of using this approach

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

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

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

  • 6

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

  • 61

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

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

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

  • 1

    我的设置分为如下

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

    我们有3个环境

    • dev

    • 分期

    • 生产环境

    现在显然,分期和 生产环境 应该具有尽可能最大的类似环境 . 所以我们两个都保持 prod.py .

    但有一种情况我必须确定正在运行的服务器是一个 生产环境 服务器 . @T . 斯通的回答帮我写了如下支票 .

    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
    
  • 7

    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路径更改为指向新的设置路径

    旧路径 - > 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 )))

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

  • -3

    我发现这里的回答很有帮助 . (这是否已经得到了更明确的解决?最后一次回复是一年前的事情 . )在考虑了所有方法之后列出来了,我想出了一个我没有看到的解决方案 .

    我的标准是:

    • 一切都应该在源代码管理中 . 我不喜欢四处闲聊 .

    • 理想情况下,将设置保存在一个文件中 . 如果我不正确看待他们,我会忘记的事情:)

    • 无需手动编辑即可部署 . 应该能够使用单个结构命令进行测试/推送/部署 .

    • 避免将开发设置泄漏到 生产环境 中 .

    • 尽可能靠近"standard"(咳嗽)Django布局 .

    我认为切换主机有一定意义,但后来认为这里真正的问题是针对不同环境的不同设置,并且有一个aha时刻 . 我把这段代码放在我的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'
    

    这样,应用程序默认为 生产环境 设置,这意味着您明确地是"whitelisting"您的开发环境 . 忘记在本地设置环境变量比使用其他方式更安全,并且忘记在 生产环境 中设置某些内容并使用某些开发设置 .

    在本地开发时,无论是从shell还是在.bash_profile中,或者在以下任何地方:

    $ export DJANGO_DEVELOPMENT_SERVER=yep
    

    (或者,如果您正在使用Windows进行开发,请通过控制面板或其他所谓的日期进行设置...... Windows总是让它变得如此模糊以至于您可以设置环境变量 . )

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

相关问题