在进行Django 开发时,我倾向于使用SQLite,但是在实时服务器上,通常需要更强大的功能(例如MySQL / PostgreSQL)。同样,对Django设置也有其他更改:不同的日志记录位置/强度,媒体路径等。
您如何管理所有这些更改,以使部署变得简单,自动化?
在进行Django 开发时,我倾向于使用SQLite,但是在实时服务器上,通常需要更强大的功能(例如MySQL / PostgreSQL)。同样,对Django设置也有其他更改:不同的日志记录位置/强度,媒体路径等。
您如何管理所有这些更改,以使部署变得简单,自动化?
Answers:
更新: django-configurations已发布,对于大多数人来说,它可能比手动执行更好。
如果您希望手动进行操作,则我先前的答案仍然适用:
我有多个设置文件。
settings_local.py
-特定于主机的配置,例如数据库名称,文件路径等。settings_development.py
-用于开发的配置,例如DEBUG = True
。settings_production.py
-用于生产的配置,例如SERVER_EMAIL
。我将所有这些与一个settings.py
首先导入的文件捆绑在一起settings_local.py
,然后再将另外两个文件之一捆绑在一起。它决定它通过两个设置加载内settings_local.py
- DEVELOPMENT_HOSTS
和PRODUCTION_HOSTS
。 settings.py
来电platform.node()
以查找正在其上运行的计算机的主机名,然后在列表中查找该主机名,并根据在其中找到该主机名的列表加载第二个设置文件。
这样,您真正需要担心的唯一事情就是使settings_local.py
文件与主机特定的配置保持最新,并且其他所有内容都会自动处理。
在此处查看示例。
_local
相当混乱),并且您没有使用模块(设置/base.py,设置/local.py,设置/production.py)。将其保存在单独的存储库中也是明智的选择……更好的是,一种安全的服务,可以从规范的来源提供此信息(对于大多数人来说可能过头了)……这样,新主机不需要新版本。
.py
文件中的主机列表,从而使每个主机都可以访问有关其他每个主机的配置信息,则可以对manage.py进行模板化以使用适当的设置文件在您的部署配置中。
就个人而言,我为该项目使用一个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/'
等等。可读性稍差,但是它可以正常工作,并且省去了处理多个设置文件的麻烦。
在settings.py的结尾,我有以下内容:
try:
from settings_local import *
except ImportError:
pass
这样,如果我想覆盖默认设置,则只需将settings_local.py放在settings.py旁边。
settings_local
导致ImportError
,except
则会无声地吞下它。
No module named...
vs 消息cannot import name...
,但它很脆弱。或者,将您的导入内容放在try块中的settings_local.py中,并引发一个更具体的异常:MisconfiguredSettings
或类似的结果。
我有两个文件。settings_base.py
其中包含通用/默认设置,并且已签入源代码管理。每个部署都有一个单独的settings.py
,从头from settings_base import *
开始执行,然后根据需要进行覆盖。
settings_local.py
这样做from settings import *
,它可以覆盖中的值settings.py
。(该settings_local.py
文件必须在末尾导入settings.py
)。
我发现的最简单的方法是:
1)使用默认的settings.py进行本地开发,以及2)创建一个production-settings.py,开头为:
import os
from settings import *
然后只需覆盖生产中不同的设置:
DEBUG = False
TEMPLATE_DEBUG = DEBUG
DATABASES = {
'default': {
....
}
}
在某种程度上相关,关于使用多个数据库部署Django本身的问题,您可能需要看一下Djangostack。您可以下载一个完全免费的安装程序,该程序允许您安装Apache,Python,Django等。在安装过程中,我们允许您选择要使用的数据库(MySQL,SQLite,PostgreSQL)。在内部自动进行部署时,我们会广泛使用安装程序(它们可以在无人值守模式下运行)。
我的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,这将非常危险。
除了吉姆提到的多个设置文件,我也倾向于地方两个设置成我的顶部settings.py文件BASE_DIR
和BASE_URL
设置的代码和URL到现场的基地的路径,所有其他的设置被修改将自己附加到这些。
BASE_DIR = "/home/sean/myapp/"
例如 MEDIA_ROOT = "%smedia/" % BASEDIR
因此,在移动项目时,我只需要编辑这些设置,而无需搜索整个文件。
我还建议您查看一下能够促进远程部署自动化的fabric和Capistrano(Ruby工具,但是它可以用于部署Django应用程序)。
好吧,我使用以下配置:
在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
这么多复杂的答案!
每个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
这是一个较旧的文章,但是我认为如果我添加这个有用的内容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.py或wsgi.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的服务器一起使用。
实际上,您可能应该考虑为您的开发和生产环境使用相同(或几乎相同)的配置。否则,会不时出现“嘿,它可以在我的机器上工作”之类的情况。
因此,为了自动化部署并消除那些WOMM问题,只需使用Docker即可。