【问题标题】:How to use the same settings.py for staging and production. Django如何使用相同的 settings.py 进行登台和生产。姜戈
【发布时间】:2013-09-14 23:33:36
【问题描述】:

我有许多相同的数据库实例

  • 本地主机
  • staging.server.com
  • www.server.com

我希望我的 Django 设置能够轻松选择其中任何一项。我不想保留多个设置文件。

我知道我可以像这样配置它们,但是如何切换到默认值以外的任何人。

DATABASES = {
  'default': {
    'ENGINE': 'django.db.backends.sqlite3',
    'HOST': 'localhost'
  },
  'staging': {
    'ENGINE': 'django.db.backends.sqlite3',
    'HOST': 'staging.server.com'
  },
  'production': {
    'ENGINE': 'django.db.backends.sqlite3',
    'HOST': 'www.server.com'
  }
}

【问题讨论】:

  • 使用数据库路由器,syncdb时指定数据库名
  • 很好的问题,但标题应该是“如何使用相同的 settings.py 进行暂存和生产”

标签: python database django settings


【解决方案1】:

[更新]

对于配置/代码分离,我使用了一个名为 django-decouple 的项目,而不是滚动我自己的东西,原始答案的基本原理仍然有效。

[原答案]

我建议使用环境变量而不是 if/elif 链和/或包含。主要原因是:

  • 配置因部署而异,但代码不会 - 因此您应该致力于将配置与代码严格分离。
  • 环境特定信息与环境有关 - 环境变量很容易在部署之间更改,而无需更改任何代码。
  • 避免意外将密码等敏感信息检查到源代码控制中。

例如:

DATABASES = {
    'default': {
        'ENGINE': os.environ.get('DB_NAME', 'django.db.backends.sqlite3'),
        'NAME': os.environ.get('DB_NAME', 'some_default'),
        'USER': os.environ.get('DB_USER', ''),
        'PASSWORD': os.environ.get('DB_PASS', ''),
        'HOST': os.environ.get('DB_HOST', ''),
        'PORT': '',
    }
}

请阅读“the twelve factors app”以获得有关此实践背后原理的详细说明,并阅读“stop writing settings files”以获得有关 Django 设置的实用方法。

我也推荐使用 virtualenv。一些提示:

  • 将我的应用程序放在 /opt/django-apps/project_name 之类的路径中
  • 安装virtualenvwrapper并在/var/lib/python-virtualenvs之类的某个路径下创建一个与项目同名的virtualenv
  • 当您想参与该项目时,请发送workon project_name

我像这样使用wsgi.py

import os
import site
import sys

APP_ROOT = os.path.dirname(os.path.abspath(__file__))
ROOT = os.path.dirname(APP_ROOT)
PROJECT_NAME = os.path.basename(APP_ROOT)
INSTANCE_NAME = os.path.basename(ROOT)
VENV = '/var/lib/python-virtualenvs/{}/'.format(INSTANCE_NAME)
# Add the site-packages of the chosen virtualenv to work with
site.addsitedir(VENV + 'lib/python2.7/site-packages')

# Add the app's directory to the PYTHONPATH
sys.path.append(ROOT)

# Activate your virtual env
activate_env=os.path.expanduser(VENV + "bin/activate_this.py")
execfile(activate_env, dict(__file__=activate_env))

os.environ.setdefault("DJANGO_SETTINGS_MODULE", PROJECT_NAME + ".settings")

from django.core.wsgi import get_wsgi_application
_application = get_wsgi_application()

def application(environ, start_response):
    os.environ['DEBUG'] = environ['DEBUG']
    os.environ['DB_NAME'] = environ['DB_NAME']
    os.environ['DB_PASS'] = environ['DB_PASS']
    os.environ['DB_HOST'] = environ['DB_HOST']
    os.environ['DB_USER'] = environ['DB_USER']
    return _application(environ, start_response)

【讨论】:

  • 太复杂了。我认为应该有一个更简单的解决方案。
  • 这是很多样板文件,但您无需再次触摸它,因为它适用于任何项目 - 只需照原样复制即可。
【解决方案2】:

我找到了一种方法,但我不确定这是否是正确的方法。请发表评论。

我有主要的 settings.py,其中的 DATABASES 设置看起来像...

DATABASES = {
  'default': {
    'ENGINE': 'django.db.backends.sqlite3',
    'HOST': 'www.server.com'
  }
}

在这个文件的末尾,我有以下代码...

# Load the local overrides if there are any.
try:
    from settings_local import *
except ImportError, e:
    pass

然后我在本地环境中的同一位置有一个 settings_local.py 文件,但被 Git 忽略,如下所示...

DATABASES = {
  'default': {
    'ENGINE': 'django.db.backends.sqlite3',
    'HOST': 'localhost'
  }
}

如果与 settings.py 相同的目录中没有 settings_local.py 文件,这允许我的应用程序连接到生产数据库服务器,如果此文件存在,则允许我的应用程序连接到本地(或暂存)数据库。

【讨论】:

  • 我不会将此列为配置管理的最佳实践,但很多人都这样做。它可以工作,但如果 settings_local.py 被意外部署,恢复起来可能会很麻烦,特别是如果它在一段时间内被忽视。
【解决方案3】:

所以我一直在阅读Two Scoops of Django 这本书,整个第 5 章都是基于这个问题。本章,设置和需求文件,回答了我所有的问题。本章基于Jacob Kaplan-Moss'The Best (and worst) of Django 在 OSCON 2011 上的演讲。请参阅幻灯片第 47 页及以后的内容。

基本上,这个想法是使用多个设置文件,即 settings/base.py、settings/local.py、settings/production.py 等。并在使用 --settings 开关启动服务器时使用正确的文件.

【讨论】:

    猜你喜欢
    • 2021-03-24
    • 1970-01-01
    • 2021-11-08
    • 1970-01-01
    • 1970-01-01
    • 2020-08-17
    • 2011-04-25
    • 2013-03-29
    • 2017-01-18
    相关资源
    最近更新 更多