我在进行Django开发时,倾向于使用SQLite,但在生产服务器上通常需要更强大的解决方案(比如MySQL/PostgreSQL等)。
不可避免地,还需要对Django设置进行其他更改:不同的日志记录位置/强度,媒体路径等。
那么,如何管理所有这些变化以使部署过程简单、自动化呢?
我在进行Django开发时,倾向于使用SQLite,但在生产服务器上通常需要更强大的解决方案(比如MySQL/PostgreSQL等)。
不可避免地,还需要对Django设置进行其他更改:不同的日志记录位置/强度,媒体路径等。
那么,如何管理所有这些变化以使部署过程简单、自动化呢?
.py
文件中检查主机列表,从而使每个主机都可以访问有关其他每个主机配置的信息,您可以将manage.py模板化为在部署配置中使用适当的设置文件。 - DylanYoung就我个人而言,我会为项目使用一个单独的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
语句会悄无声息地将其吞掉。 - Chris MartinNo module named...
和 cannot import name...
,但这种方法很脆弱。或者,将你的导入放在 settings_local.py
中的 try 块中,并引发一个更具体的异常:MisconfiguredSettings
或类似的异常。 - DylanYoungexcept ModuleNotFoundError
。 - warvariuc我有两个文件。 settings_base.py
包含常见/默认设置,并已检入源代码控制系统。每次部署都有单独的 settings.py
,它在开头执行 from settings_base import *
,然后根据需要进行覆盖。
settings_local.py
中使用了 from settings import *
,那么它可以覆盖 settings.py
中的值(要在 settings.py
的末尾导入 settings_local.py
文件)。 - Sethimport os
from settings import *
然后只需覆盖在生产环境中不同的设置:
DEBUG = False
TEMPLATE_DEBUG = DEBUG
DATABASES = {
'default': {
....
}
}
与此有些相关的是,如果你需要使用多个数据库部署Django本身,你可以看一下Djangostack。你可以下载一个完全免费的安装程序,它允许你安装Apache、Python、Django等等。在安装过程中,我们允许你选择要使用哪个数据库(MySQL、SQLite、PostgreSQL)。我们在内部自动化部署时广泛使用这些安装程序(它们可以以无人值守模式运行)。
嗯,我使用这个配置:
在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
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
if(DEBUG):
#Debug setting
else:
#Release setting
为什么要把事情搞得这么复杂?我从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
文件相同的文件夹中创建另一个.env.example
文件,以便您可以拥有.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
我将我的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文件,这将非常危险。