How do you configure Django for simple development and deployment?
我在做Django的时候经常用sqlite开发,但在实时服务器上,更强大的功能是经常需要(例如mysql/postgresql)。总是有其他的变化要对姜戈设置:不同的日志记录位置/强度,媒体路径等。
如何管理所有这些更改以使部署成为简单、自动化的流程?
更新:Django配置已经发布,这对于大多数人来说可能是一个更好的选择,而不是手工操作。
如果您愿意手动操作,我之前的回答仍然适用:
我有多个设置文件。
settings_local.py —特定于主机的配置,如数据库名称、文件路径等。settings_development.py —用于开发的配置,例如DEBUG = True 。settings_production.py —用于生产的配置,例如SERVER_EMAIL 。
我把这些都和一个
这样一来,您真正需要担心的是保持
在这里查看一个示例。
就我个人而言,我在项目中使用了single settings.py,我只是让它查找它所使用的主机名(我的开发机器有以"gabriel"开头的主机名,所以我有:
1 2 3 4 5 | import socket if socket.gethostname().startswith('gabriel'): LIVEHOST = False else: LIVEHOST = True |
在其他方面,我也有这样的事情:
1 2 3 4 5 6 7 8 | 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的末尾,我有以下内容:
1 2 3 4 | try: from settings_local import * except ImportError: pass |
这样,如果我想覆盖默认设置,我只需要将settings_local.py放在settings.py旁边。
我有两个文件。
我发现最简单的方法是:
1)使用默认设置.py进行本地开发和2)创建production-settings.py开始于:
1 2 | import os from settings import * |
然后只需覆盖生产中不同的设置:
1 2 3 4 5 6 7 8 9 | DEBUG = False TEMPLATE_DEBUG = DEBUG DATABASES = { 'default': { .... } } |
有点相关,对于将django本身部署到多个数据库中的问题,您可能需要查看djangostack。您可以下载一个完全免费的安装程序,它允许您安装Apache、python、django等。作为安装过程的一部分,我们允许您选择要使用的数据库(mysql、sqlite、postgresql)。我们在内部自动化部署时广泛使用安装程序(它们可以在无人值守模式下运行)。
好吧,我使用这个配置:
在settings.py的末尾:
1 2 3 4 5 | #settings.py try: from locale_settings import * except ImportError: pass |
在locale_settings.py中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | #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文件在一个外部目录中。这样,它就不会签入源代码管理,也不会被部署重写。我把它和任何默认设置放在我的django项目下的settings.py文件中:
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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,这是非常危险的。
除了Jim提到的多个设置文件之外,我还倾向于将两个设置放在我的settings.py文件中,分别放在代码路径和站点底部的URL的顶部
所以在移动项目时,我只需要编辑这些设置,而不需要搜索整个文件。
我还建议查看Fabric和Capistrano(Ruby工具,但它可以用于部署Django应用程序),这有助于远程部署的自动化。
这是一个旧的帖子,但我认为如果我添加这个有用的
使用Django配置
快速启动1 | pip install django-configurations |
然后在项目的settings.py或任何其他用于存储设置常量的模块中对包含的configuration s.configuration类进行子类划分,例如:
1 2 3 4 5 6 | # mysite/settings.py from configurations import Configuration class Dev(Configuration): DEBUG = True |
将
以及模块导入路径的
或者,当沿着Django的默认
要使django能够使用您的配置,您现在必须修改manage.py或wsgi.py脚本,以使用django配置的相应启动程序函数版本,例如使用django配置的典型manage.py如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 | #!/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行中,我们不使用通用工具
这同样适用于wsgi.py文件,例如:
1 2 3 4 5 6 7 8 | 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() |
这里我们不使用默认的
就是这样!现在,您可以将项目与manage.py和您最喜爱的支持wsgi的服务器一起使用。
这么多复杂的答案!
每个settings.py文件都附带:
1 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) |
我使用该目录设置这样的调试变量(使用dev代码所在的directoy获取):
1 2 3 | DEBUG=False if(BASE_DIR=="/path/to/my/dev/dir"): DEBUG = True |
然后,每次移动settings.py文件时,debug都将为false,这是您的生产环境。
每次需要不同于开发环境中的设置时,只需使用:
1 2 3 4 | if(DEBUG): #Debug setting else: #Release setting |
我使用环境:
1 2 3 4 | if os.environ.get('WEB_MODE', None) == 'production' : from settings_production import * else : from settings_dev import * |
我相信这是一种更好的方法,因为最终您需要为您的测试环境进行特殊的设置,并且您可以很容易地将其添加到这个条件中。
我认为这取决于站点的大小,以及您是否需要从使用sqlite开始,我已经在几个较小的活动站点上成功地使用了sqlite,并且运行良好。
实际上,您可能应该考虑为您的开发和生产环境进行相同(或几乎相同)的配置。否则,像"嘿,它在我的机器上工作"这样的情况会不时发生。
所以为了自动化您的部署并消除这些WOMM问题,只需使用Docker。