简体   繁体   English

如何使用相同的settings.py进行分段和生产。 Django的

[英]How to use the same settings.py for staging and production. Django

I have many identical database instances 我有许多相同的数据库实例

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

I want my Django settings to be able to chose any one of these with minimal efforts. 我希望我的Django设置能够以最小的努力选择其中任何一个。 I don't want to keep multiple setting files. 我不想保留多个设置文件。

I know I can configure them like this but how to switch to anyone other than the default. 我知道我可以像这样配置它们但是如何切换到默认值以外的任何人。

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'
  }
}

[update] [更新]

For config/code separation I'm using a project called django-decouple instead of rolling my own stuff, the rationale of the original answer remains valid. 对于配置/代码分离,我使用的是一个名为django-decouple的项目,而不是滚动我自己的东西,原始答案的基本原理仍然有效。

[original answer] [原始答案]

I recommend using environment variables instead of if/elif chains and/or includes. 我建议使用环境变量而不是if / elif链和/或包含。 The main reasons are: 主要原因是:

  • config varies substantially across deploys, code does not - hence you should aim to strict separation of config from code. 配置在部署之间变化很大,代码没有 - 因此您应该将配置与代码严格分开。
  • environment specific information pertains to the environment - env vars are easy to change between deploys without changing any code. 环境特定信息与环境有关 - env vars很容易在部署之间更改,而无需更改任何代码。
  • avoids checking sensitive information like passwords into source control by accident. 避免意外地将密码等敏感信息检入源代码控制。

For example: 例如:

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': '',
    }
}

Please read " the twelve factors app " for a longer explanation on the principles behind this practice and " stop writing settings files " for a practical approach to Django settings. 请阅读“ 十二个因子应用程序 ”以获得有关此实践背后原理的更长解释,并“ 停止编写设置文件 ”以获取Django设置的实用方法。

I also recommend using virtualenv. 我还建议使用virtualenv。 Some tips: 一些技巧:

  • place my apps in a path like /opt/django-apps/project_name 将我的应用程序放在/ opt / django-apps / project_name之类的路径中
  • install virtualenvwrapper and make a virtualenv with the same name of the project under some path like /var/lib/python-virtualenvs 安装virtualenvwrapper并使用/var/lib/python-virtualenvs类的路径创建一个与项目名称相同/var/lib/python-virtualenvs
  • issue a workon project_name when you want to work at the project 如果要在项目中工作,请发出workon project_name

I use a wsgi.py like this: 我使用像这样的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)

I found a way but I am not sure if this is the proper way to do it. 我找到了一种方法,但我不确定这是否是正确的方法。 Please comment. 请评论。

I have the main settings.py and the DATABASES setting in it look like... 我有主要的settings.py和DATABASES设置看起来像......

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

And at the end of this file, I have the following code... 在这个文件的末尾,我有以下代码......

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

Then I have a settings_local.py file in the same location, but ignored by Git, on my local environment as follows... 然后我在同一位置有一个settings_local.py文件,但在我的本地环境中被Git忽略,如下所示......

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

This allows my application to connect to the production database server if there is no settings_local.py file in the same directory as settings.py, and to the local (or staging) database if this file exists. 如果在settings.py所在的目录中没有settings_local.py文件,则此应用程序可以连接到生产数据库服务器,如果此文件存在,则允许连接到本地(或登台)数据库。

So I've been reading the book Two Scoops of Django and the whole chapter 5 is based upon this issue. 所以我一直在阅读Django的Two Scoops一书,整个第5章都基于这个问题。 This chapter, Settings and Requirement Files , answers all of my questions. 本章“设置和需求文件 ”回答了我的所有问题。 This chapter is based upon Jacob Kaplan-Moss ' The Best (and worst) of Django talk at OSCON 2011. See page 47 and onwards of the slide. 本章基于Jacob Kaplan-Moss在2011年OSCON上的Django最佳(也是最差)演讲。请参阅第47页及其后的幻灯片。

Basically, the idea is to use multiple settings files ie, settings/base.py, settings/local.py, settings/production.py etc. And to use the proper one while launching the server using the --settings switch. 基本上,我们的想法是使用多个设置文件,即settings / base.py,settings / local.py,settings / production.py等。并在使用--settings开关启动服务器时使用正确的文件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM