116

在进行Django开发时,我倾向于使用SQLite ,但在实时服务器上,通常需要更健壮的东西(例如MySQL / PostgreSQL)。总是对 Django 设置进行其他更改:不同的日志记录位置/强度、媒体路径等。

您如何管理所有这些更改以使部署成为一个简单、自动化的过程?

4

15 回答 15

86

更新: django-configurations已经发布,对于大多数人来说,这可能是比手动操作更好的选择。

如果您更愿意手动执行操作,我之前的回答仍然适用:

我有多个设置文件。

  • settings_local.py- 特定于主机的配置,例如数据库名称、文件路径等。
  • settings_development.py- 用于开发的配置,例如DEBUG = True.
  • settings_production.py- 用于生产的配置,例如SERVER_EMAIL

我将这些都与一个settings.py首先导入的文件联系在一起settings_local.py,然后是另外两个中的一个。它通过settings_local.py-DEVELOPMENT_HOSTSPRODUCTION_HOSTS. settings.py调用platform.node()以查找正在运行的机器的主机名,然后在列表中查找该主机名,并根据在哪个列表中找到主机名来加载第二个设置文件。

这样,您真正需要担心的唯一一件事就是使settings_local.py文件与特定于主机的配置保持同步,而其他一切都会自动处理。

在这里查看一个示例。

于 2008-09-17T22:27:35.390 回答
26

就个人而言,我为项目使用了一个 settings.py,我只是让它查找它所在的主机名(我的开发机器的主机名以“gabriel”开头,所以我只有这个:

import socket
if socket.gethostname().startswith('gabriel'):
    LIVEHOST = False
else: 
    LIVEHOST = True

然后在其他部分我有类似的东西:

if LIVEHOST:
    DEBUG = False
    PREPEND_WWW = True
    MEDIA_URL = 'http://static1.grsites.com/'
else:
    DEBUG = True
    PREPEND_WWW = False
    MEDIA_URL = 'http://localhost:8000/static/'

等等。可读性差一点,但它工作正常并且不必处理多个设置文件。

于 2008-09-18T03:45:38.247 回答
25

在 settings.py 的末尾,我有以下内容:

try:
    from settings_local import *
except ImportError:
    pass

这样,如果我想覆盖默认设置,我只需将 settings_local.py 放在 settings.py 旁边。

于 2008-09-18T10:57:14.793 回答
11

我有两个文件。settings_base.py其中包含常见/默认设置,并已签入源代码管理。每个部署都有一个单独的settings.py,它from settings_base import *在开始时执行,然后根据需要覆盖。

于 2008-09-17T22:29:30.783 回答
7

我发现的最简单的方法是:

1) 使用默认settings.py进行本地开发和 2) 创建一个production-settings.py,开头为:

import os
from settings import *

然后只需覆盖生产中不同的设置:

DEBUG = False
TEMPLATE_DEBUG = DEBUG


DATABASES = {
    'default': {
           ....
    }
}
于 2010-07-08T07:38:28.410 回答
2

有点相关,对于部署 Django 本身与多个数据库的问题,你可能想看看Djangostack。您可以下载一个完全免费的安装程序,允许您安装 Apache、Python、Django 等。作为安装过程的一部分,我们允许您选择要使用的数据库(MySQL、SQLite、PostgreSQL)。在内部自动化部署时,我们广泛使用安装程序(它们可以在无人值守模式下运行)。

于 2011-07-27T15:20:25.783 回答
1

好吧,我使用这个配置:

在 settings.py 的末尾:

#settings.py
try:
    from locale_settings import *
except ImportError:
    pass

在 locale_settings.py 中:

#locale_settings.py
class Settings(object):

    def __init__(self):
        import settings
        self.settings = settings

    def __getattr__(self, name):
        return getattr(self.settings, name)

settings = Settings()

INSTALLED_APPS = settings.INSTALLED_APPS + (
    'gunicorn',)

# Delete duplicate settings maybe not needed, but I prefer to do it.
del settings
del Settings
于 2011-08-13T00:16:52.940 回答
1

除了 Jim 提到的多个设置文件之外,我还倾向于将两个设置放入我的 settings.py 文件顶部BASE_DIRBASE_URL设置为代码的路径和站点基础的 URL,所有其他设置都修改将自己附加到这些。

BASE_DIR = "/home/sean/myapp/" 例如MEDIA_ROOT = "%smedia/" % BASEDIR

因此,在移动项目时,我只需要编辑这些设置,而不是搜索整个文件。

我还建议查看 Fabric 和Capistrano(Ruby 工具,但它可用于部署 Django 应用程序),它们有助于远程部署的自动化。

于 2008-09-18T01:59:37.847 回答
1

我在外部目录中有我的 settings.py 文件。这样,它就不会被检查到源代码控制中,也不会被部署覆盖。我把它和任何默认设置一起放在我的 Django 项目下的 settings.py 文件中:

import sys
import os.path

def _load_settings(path):    
    print "Loading configuration from %s" % (path)
    if os.path.exists(path):
    settings = {}
    # execfile can't modify globals directly, so we will load them manually
    execfile(path, globals(), settings)
    for setting in settings:
        globals()[setting] = settings[setting]

_load_settings("/usr/local/conf/local_settings.py")

注意:如果您不能信任 local_settings.py,这是非常危险的。

于 2009-10-06T18:22:51.197 回答
1

这么多复杂的答案!

每个 settings.py 文件都附带:

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

我使用该目录来设置 DEBUG 变量,如下所示(用你的开发代码所在的目录重新放置):

DEBUG=False
if(BASE_DIR=="/path/to/my/dev/dir"):
    DEBUG = True

然后,每次移动 settings.py 文件时,DEBUG 将为 False,它是您的生产环境。

每次您需要与开发环境中的设置不同的设置时,只需使用:

if(DEBUG):
    #Debug setting
else:
    #Release setting
于 2018-02-22T22:02:53.753 回答
0

我使用环境:

if os.environ.get('WEB_MODE', None) == 'production' :
   from settings_production import *
else :
   from settings_dev import *

我相信这是一种更好的方法,因为最终您需要为您的测试环境进行特殊设置,并且您可以轻松地将其添加到此条件中。

于 2012-03-14T02:04:30.470 回答
0

我认为这取决于站点的大小,是否需要停止使用 SQLite,我已经在几个较小的实时站点上成功地使用了 SQLite,并且运行良好。

于 2008-09-20T15:37:23.877 回答
0

这是一篇较旧的帖子,但我认为如果我添加此有用的library内容,它将简化事情。

使用django 配置

快速开始

pip install django-configurations

然后在项目的 settings.py 或您用于存储设置常量的任何其他模块中对包含的configurations.Configuration 类进行子类化,例如:

# mysite/settings.py

from configurations import Configuration

class Dev(Configuration):
    DEBUG = True

DJANGO_CONFIGURATION环境变量设置为您刚刚创建的类的名称,例如~/.bashrc

export DJANGO_CONFIGURATION=Dev

DJANGO_SETTINGS_MODULE往常一样将环境变量添加到模块导入路径中,例如在 bash 中:

export DJANGO_SETTINGS_MODULE=mysite.settings

或者--configuration,在使用 Django 管理命令时按照 Django 的默认命令行选项提供该--settings选项,例如:

python manage.py runserver --settings=mysite.settings --configuration=Dev

为了使 Django 能够使用您的配置,您现在必须修改您的manage.pywsgi.py脚本以使用 django-configurations 的相应启动器功能版本,例如,使用 django-configurations 的典型manage.py如下所示:

#!/usr/bin/env python

import os
import sys

if __name__ == "__main__":
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mysite.settings')
    os.environ.setdefault('DJANGO_CONFIGURATION', 'Dev')

    from configurations.management import execute_from_command_line

    execute_from_command_line(sys.argv)

请注意,在第 10 行中,我们没有使用 common 工具django.core.management.execute_from_command_line,而是使用configurations.management.execute_from_command_line.

这同样适用于您的wsgi.py文件,例如:

import os

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mysite.settings')
os.environ.setdefault('DJANGO_CONFIGURATION', 'Dev')

from configurations.wsgi import get_wsgi_application

application = get_wsgi_application()

这里我们不使用默认django.core.wsgi.get_wsgi_application函数,而是使用configurations.wsgi.get_wsgi_application.

而已!您现在可以将您的项目与manage.py和您最喜欢的启用 WSGI 的服务器一起使用。

于 2018-05-10T21:38:54.010 回答
0

为什么要把事情搞得这么复杂?我从 PHP/Laravel 背景进入 Django。我使用.env,您可以轻松配置它。

安装这个包

django-environ

现在,在您所在的文件夹中settings.py,创建一个文件.env(确保将此文件放在 gitignore 中)

.env文件中,放置环境变量,如调试设置状态、密钥、邮件凭据等示例快照.env

SECRET_KEY="django-insecure-zy%)s5$=aql=#ox54lzfjyyx!&uv1-q0kp^54p(^251&_df75i"

DB_NAME=bugfree
DB_USER=postgres
DB_PASSWORD=koushik
DB_PORT=5433
DB_HOST=localhost

APP_DEBUG=True # everything is string here

在设置中,确保使用此实例化它

import environ
env = environ.Env()
environ.Env.read_env()

现在您可以从.env文件中导入值并将它们放在您想要的任何位置。中的一些例子settings.py

SECRET_KEY = env('SECRET_KEY')
DEBUG = bool(env('APP_DEBUG', False))

您也可以像这样输入默认值

env('DB_NAME', 'default value here')

提示 您可以在您创建.env.example文件的同一文件夹中创建另一个,.env并且您可以拥有一个模板.env并且您可以提交该.example文件。它可以帮助未来的开发人员轻松了解那里有哪些环境变量。 .env.example会是这样的

SECRET_KEY=VALUE_HERE

DB_NAME=VALUE_HERE
DB_USER=VALUE_HERE
DB_PASSWORD=VALUE_HERE
DB_PORT=VALUE_HERE
DB_HOST=VALUE_HERE

EMAIL_HOST=VALUE_HERE
EMAIL_PORT=VALUE_HERE
EMAIL_HOST_USER=VALUE_HERE
EMAIL_HOST_PASSWORD=VALUE_HERE
DEFAULT_FROM_EMAIL=VALUE_HERE
于 2021-06-13T15:27:40.820 回答
-2

事实上,您可能应该考虑为您的开发和生产环境使用相同(或几乎相同)的配置。否则,“嘿,它在我的机器上工作”之类的情况会时不时发生。

因此,为了使您的部署自动化并消除这些 WOMM 问题,只需使用Docker即可。

于 2016-12-22T14:36:42.840 回答