如何配置Django以进行简单的开发和部署?


112

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

您如何管理所有这些更改,以使部署变得简单,自动化?


我显然不喜欢任何人做任何事情:)。我只是利用django提供的ORM。
Andrew Sledge

1
问题是如何自动更改设置以在环境之间切换:-)
Guruprasad


您可以看一下这个软件包:django-split-settings
sobolevn 2015年

Answers:


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_HOSTSsettings.py来电platform.node()以查找正在其上运行的计算机的主机名,然后在列表中查找该主机名,并根据在其中找到该主机名的列表加载第二个设置文件。

这样,您真正需要担心的唯一事情就是使settings_local.py文件与主机特定的配置保持最新,并且其他所有内容都会自动处理。

在此处查看示例。


2
如果登台(开发)和生产在同一台机器上怎么办?platform.node()返回相同的值。
gwaramadze 2013年

2
示例链接已关闭。
杰克森

根据主持人名单确定设置的好主意!我的第一个选择就是命名法(settings_local.py始终是第一个导入的,因此任何不会被覆盖的设置实际上仍将在生产中处于活动状态,从而使后缀_local相当混乱),并且您没有使用模块(设置/base.py,设置/local.py,设置/production.py)。将其保存在单独的存储库中也是明智的选择……更好的是,一种安全的服务,可以从规范的来源提供此信息(对于大多数人来说可能过头了)……这样,新主机不需要新版本。
DylanYoung '17

更好的是,如果您使用的是计算机管理软件,则无需检查.py文件中的主机列表,从而使每个主机都可以访问有关其他每个主机的配置信息,则可以对manage.py进行模板化以使用适当的设置文件在您的部署配置中。
DylanYoung '17

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

等等。可读性稍差,但是它可以正常工作,并且省去了处理多个设置文件的麻烦。


我喜欢这个主意,但是不允许我区分在同一主机上运行的不同Django实例。例如,如果您在同一主机上为不同的子域运行了不同的实例,则会发生这种情况。
Erik

24

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

try:
    from settings_local import *
except ImportError:
    pass

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


4
这有点危险,因为如果输入错字会settings_local导致ImportErrorexcept则会无声地吞下它。
克里斯·马丁

您可以查看No module named...vs 消息cannot import name...,但它很脆弱。或者,将您的导入内容放在try块中的settings_local.py中,并引发一个更具体的异常:MisconfiguredSettings或类似的结果。
DylanYoung '17

11

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


1
我也用这个 它优于逆设置(在settings.py末尾带有dmishe的“ from settings_local import *”),因为它允许本地设置在需要时访问和修改全局设置。
卡尔·梅耶

3
如果settings_local.py这样做from settings import *,它可以覆盖中的值settings.py。(该settings_local.py文件必须在末尾导入settings.py)。
塞斯,

无论如何都可以做到。看看上面的stackoverflow.com/a/7047633/3124256。@Seth这是循环导入的秘诀。
DylanYoung '17

7

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

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

import os
from settings import *

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

DEBUG = False
TEMPLATE_DEBUG = DEBUG


DATABASES = {
    'default': {
           ....
    }
}

2

在某种程度上相关,关于使用多个数据库部署Django本身的问题,您可能需要看一下Djangostack。您可以下载一个完全免费的安装程序,该程序允许您安装Apache,Python,Django等。在安装过程中,我们允许您选择要使用的数据库(MySQL,SQLite,PostgreSQL)。在内部自动进行部署时,我们会广泛使用安装程序(它们可以在无人值守模式下运行)。


1
另外,我想推荐基于预装django的Ubuntu * NIX堆栈的Django Turnkey Linux
jochem 2011年

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,这将非常危险。


1

除了吉姆提到的多个设置文件,我也倾向于地方两个设置成我的顶部settings.py文件BASE_DIRBASE_URL设置的代码和URL到现场的基地的路径,所有其他的设置被修改将自己附加到这些。

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

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

我还建议您查看一下能够促进远程部署自动化的fabric和Capistrano(Ruby工具,但是它可以用于部署Django应用程序)。


Ansible是python,它提供了比Fabric更强大的配置功能。他们也很好地配对。
DylanYoung '17

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

1

这么多复杂的答案!

每个settings.py文件都附带:

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

我使用该目录来设置DEBUG变量,如下所示(用您的开发代码所在的directoy代替):

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

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

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

if(DEBUG):
    #Debug setting
else:
    #Release setting

0

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


0

我使用环境:

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

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


0

这是一个较旧的文章,但是我认为如果我添加这个有用的内容library,它将简化事情。

使用Django配置

快速开始

pip install django-configurations

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

# 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行中,我们不使用通用工具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的服务器一起使用。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.