Django buildout 配方
项目描述
此配方允许您通过 zc.buildout 设置 Django 项目。
使用方法
此配方的重点是抽象化 settings.py 文件,使设置位于构建中而不是代码中(例如,在版本控制方面导致尴尬的处理)。settings.py 文件由模板生成,无论是默认模板、默认模板和一个用户扩展,还是完全新的模板。
该模板使用 Tempita 模板系统。
此配方的最基本用法如下
[buildout] parts = django [django] recipe = djc.recipe project = my.project
其中 my.project 是一个可导入的包,其中包含一个 urls 模块和一个 templates 目录。
正如您所看到的,这里指定的选项非常少:默认值用于构建 settings.py 文件。
运行测试
位于包内的 README.txt 同时也作为主要的 doctest。
要运行测试,请检出源代码,然后启动 buildout 并运行构建。
$ python bootstrap.py $ bin/buildout
然后您可以使用以下命令运行测试:
$ bin/test
链接
详细文档
选项
此食谱的选项不是固定的,因为其中许多只在设置模板文件中专用(参见模板化)。
这里我们展示了对食谱有影响的选项:
- 项目
这标识了一个可以充当项目包的 Python 模块(以点分隔的表示法)。项目包的最低要求是包含一个 urls.py 文件和一个 templates 目录。除非同时定义了 urlconf 和 templates 选项,否则这是必需的。
- urlconf
标识包含 URL 定义的模块:如果省略,则使用 project 中给出的模块内的 urls.py 文件。
- 模板
标识模板目录。如果省略,则使用 project 中给出的模块内名为 templates 的目录。
- 静态目录
标识静态内容(图像、CSS 和 JavaScript)将放入的文件夹。相对路径被视为相对于 buildout 目录的相对路径。如果不存在,则创建该目录,如果已存在则不做任何操作。如果省略,则默认为 static。
- 媒体目录
标识上传文件将放入的文件夹。如果省略,则默认为 media。
- 设置模板
如果指定,将使用指定的模板生成 settings.py 文件;如果没有提供,则使用默认模板。有关更多详细信息,请参阅 模板化。
- 设置模板扩展
如果指定,则将指定的模板附加到 settings template 指定的模板或默认模板。
- 静态源
如果指定,则定义从其中复制必须放入 static-directory 的静态文件的目录:有关更多详细信息,请参阅 静态源。
- 链接静态源
布尔值,默认为 false。如果设置,则文件将通过符号链接而不是复制。仅在 Unix 上工作。
- 媒体源
如果指定,则定义从其中复制必须放入 media-directory 的数据文件的目录:有关详细信息,请参阅 static-origin 选项。
- 基本设置
一个设置模块(只有绝对导入),由当前设置扩展,例如 my.module.settings。如果指定,则 apps、middleware 和 template-loaders 的默认值变为空字符串(导致它们根本不会被写入)。默认情况下不设置。
- WSGI
默认为 false。如果设置为 true(或 on 或 1),将在 parts/$partname 中创建一个名为 $partname.wsgi.py 的脚本,该脚本可以用作 Apache 或其他支持 WSGI 的 web 服务器中的 WSGI 脚本。
- wsgi-logfile
如果设置,日志将被重定向到这里:默认不设置。
- wsgi-loglevel
设置日志级别:只有在 wsgi-loglevel 也设置的情况下才会处理。接受的值有:debug、info、warning、error、critical
- coding
结果设置文件的编码。默认为 utf-8。
高级选项
支持以下高级选项
- extra-paths
一些非标准路径,其中包含额外的 Python 模块。
- pth-files
一些 pth 文件,从中加载额外的 Python 模块,这些模块应存在于 buildout 中。
- initialization
允许添加额外的 Python 代码到 manage 和 WSGI 脚本中:有关详细信息,请参阅 自定义初始化。
- environment-vars
允许在 manage.py 运行时通过设置它们来覆盖操作系统环境变量。每行一个环境变量名称和值,用空格分隔。变量值可以是硬编码的,也可以使用 buildout 模板机制,其中您引用 buildout 中设置的其它变量。
示例
environment-vars = GOOGLE_APPENGINE_PROJECT_ROOT ${buildout:appengine-base-path} TZ Europe/Helsinki
如果您希望扩展现有的环境变量,如 PATH,则可能还想检查 gocept.recipe.env buildout 脚本。有关详细信息及示例,请参阅 自定义初始化。
模板
settings.py 文件通过将 buildout 节的选项与模板进行插值生成,无论是默认模板还是由 settings-template 选项提供的模板。
模板必须是有效的 Tempita 模板,它将当前 buildout 节的所有选项作为命名空间传递,如下所示
在选项名称中,所有连字符(-)都转换为下划线(_)
添加了 name 和 secret 选项,分别映射到 buildout 节名称和随机生成的密钥 [1]。
命名空间中添加了一系列函数,以简化某些情况的处理,以下将提供更多详细信息。
函数
可以在模板中使用一定数量的函数
- absolute_url
接受一个路径,如果它是相对的,则将其与 buildout 位置连接起来以使其成为绝对路径。
- listify
接受一段数据,将其拆分为行,修剪这些行并返回获得列表,从中清除空字符串。
- rfc822tuplize
这个函数相当专业,接受任何符合 Full Name <email.address@example.com> 格式的字符串,并将其转换为包含全名和电子邮件地址的元组。如果提供的数据不符合特定要求,它将返回包含不变数据的元组。
- boolify
该函数返回True,如果传入的数据是任何以下值:True、on、1(不区分大小写)否则返回False
- join
相当于字符串的join()方法,其中要连接的数据作为第一个参数,infix作为第二个参数,以及两个可选参数prefix(添加到开头)和suffix(添加到结尾)
- dump
是repr的别名。
默认模板选项
默认模板接受许多选项。如果省略,则认为它们都是可选的,因为会提供合理的默认值。
- database
默认Django数据库的设置,形式为engine=<backend> (user=<user> password=<password>) (host=<host>) (port=<port>) name=<name> (options=(<options>))。括号中的值被视为可选。需要注意的是,选项应包含在括号(()中,以逗号分隔,并采用形式<name>=<value>。一个示例URL可能为:engine=django.db.backends.mysql user=usr password=pwd host=localhost port=3306 name=mydb options=(opt1=val1,opt2=val2)其中usr、pwd、mydb等应替换为您的配置值。默认为engine=django.db.backends.sqlite3 name=/${buildout:directory}/storage.db
- additional-databases
以name=parameters的形式列出数据库,每行一个,其中name是Django内部数据库名称,而parameters是数据库设置,其形式与database提供的相同
- media-url
静态内容前缀路径。默认为media
- admin-media
仅管理员使用的静态内容前缀路径。默认为admin_media
- timezone
时区:默认为America/Chicago
- language-code
语言代码:默认为en-us
- use-l10n
是否使用l10n:默认为true
- server-mail
来自site-generate邮件的电子邮件地址。默认为root@localhost
- admins
以RFC822格式列出的网站管理员列表。默认为John Smith <root@localhost>
- managers
管理员列表:与admins相同。默认复制admins的值
- middleware
要加载的中介类列表。如果为空字符串,则根本不写入值。
- apps
要加载的应用程序列表。如果为空,则不写入任何值。
- template-loaders
要使用的模板加载器列表。如果为空,则不写入任何值。
- debug
如果为true,则激活调试模式。默认为false
- internal-ips
在调试时允许查看完整堆栈跟踪的IP地址。默认为127.0.0.1
- site-id
Django站点ID。默认未设置。
- template-context-processors
Django模板上下文处理器。默认未设置。
- authentication-backends
Django身份验证后端。默认未设置
- languages
支持的语言列表以 代码 全称 的形式给出,例如 en-us 英语 (美国)。默认为未设置。
- mail-backend
要使用的邮件后端。默认为 django.core.mail.backends.smtp.EmailBackend。
- mail-filepath
如果使用文件邮件后端,请使用此目录。
- smtp-host
发送邮件时使用的 SMTP 服务器。默认为未设置。
- smtp-port
SMTP 服务器端口。默认为未设置。
- smtp-user
连接到 SMTP 服务器的用户名。默认为未设置。
- smtp-password
连接到 SMTP 服务器的密码。如果未设置 smtp-user,则此密码无效。默认为未设置。
- smtp-tls
连接到 SMTP 服务器时是否使用 TLS(布尔选项)。默认为 false。
- site-domain
网站域名。默认为未设置。
- site-name
网站标题。默认为未设置。
- cache-backend
缓存后端。默认为 locmem:///。
- cache-timeout
缓存超时时间(秒)。默认为 60*5。
- cache-prefix
缓存前缀(前缀于所有缓存 ID)。默认为 Z。
- fixture-dirs
搜索 fixtures 的目录。默认未设置。
已弃用选项
这些选项仍在模板中受支持,但它们将等待删除。
- database-engine
要使用的数据库引擎。
- database-name
要使用的数据库名称。
- database-user
连接到数据库服务器时使用的用户名。默认为空字符串。
- database-password
连接到数据库服务器时使用的密码。默认为空字符串。
- database-host
数据库服务器所在的宿主机。默认为空字符串。
- database-port
数据库服务器接受连接的端口。默认为空字符串。
示例用法
首先,我们需要有一个 Django 项目 egg。我们为了测试制作了一个非常简单的 egg,并将其源分发放在 packages 目录下。
当然,您还可以通过其他方式分发和获取项目 egg:例如,在开发过程中,建议使用 mr.developer。
清除这些后,我们使用此配方创建了一个最简单的 buildout
>>> write('buildout.cfg', ... """ ... [buildout] ... parts = django ... offline = false ... download-cache = %s ... newest = false ... index = http://pypi.python.org/simple/ ... find-links = packages ... ... [django] ... recipe = djc.recipe ... project = dummydjangoprj ... """ % cache_dir)
然后运行它
>>> print "start\n", system(buildout) start ... Installing django. Getting distribution for 'dummydjangoprj'. ... django: Generating settings in ... django: Making empty static directory ... django: Creating script at ... Generated script ... ... <BLANKLINE>
这为我们生成了一些文件和目录
位于 bin/django 的 Django manage.py 包装器
位于 static 的媒体目录(为空,默认选项)
位于 parts/django/djc_recipe_django/settings.py 的设置文件
所以,正如我们所见,我们在根目录中有一个 static 目录,一个 bin/django 脚本和一个 parts/django 部分
>>> ls(sample_buildout) - .installed.cfg - .secret.cfg d bin - buildout.cfg d develop-eggs d eggs d media d packages d parts d src d static >>> ls('bin') - buildout - django >>> ls('parts') d buildout d django
让我们首先看看这个
>>> ls('parts', 'django') d djc_recipe_django >>> ls('parts', 'django', 'djc_recipe_django') - __init__.py - settings.py
因此,我们可以看到 djc_recipe_django 实际上是一个可导入的 Python 模块。
如果我们检查它
>>> cat('parts', 'django', 'djc_recipe_django', 'settings.py') # coding=utf-8 SERVER_EMAIL = 'root@localhost' ADMINS = ( <BLANKLINE> ('John Smith', 'root@localhost'), ) MANAGERS = ADMINS <BLANKLINE> <BLANKLINE> DATABASES = {'default': {'ENGINE': 'django.db.backends.sqlite3', 'NAME': '/sample-buildout/storage.db'}} <BLANKLINE> TIME_ZONE = 'America/Chicago' <BLANKLINE> LANGUAGE_CODE = 'en-us' <BLANKLINE> USE_L10N = True <BLANKLINE> STATIC_ROOT = '.../static' <BLANKLINE> STATIC_URL = '/static/' <BLANKLINE> MEDIA_ROOT = '.../media' <BLANKLINE> MEDIA_URL = '/media/' <BLANKLINE> ADMIN_MEDIA_PREFIX = '/admin_media/' <BLANKLINE> SECRET_KEY = '...' <BLANKLINE> ROOT_URLCONF = 'dummydjangoprj.urls' <BLANKLINE> <BLANKLINE> TEMPLATE_DIRS = ( '.../dummydjangoprj/templates', ) <BLANKLINE> EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' EMAIL_USE_TLS = False <BLANKLINE> CACHE_BACKEND = 'locmem:///' CACHE_TIMEOUT = 60*5 CACHE_PREFIX = 'Z' <BLANKLINE> DEBUG = False TEMPLATE_DEBUG = DEBUG
如你所见,这基本上是 Django 的标准 settings.py,由 Django 的 django-admin 创建。它有一个特殊性,即它不在模块中,而是在运行时作为一个名为 _django_settings 的 幽灵 模块加载到适当的 manage 脚本中。
让我们看看 manage 脚本
>>> cat('bin', 'django') #!... <BLANKLINE> import sys sys.path[0:0] = [ ... ] <BLANKLINE> import djc.recipe.manage <BLANKLINE> if __name__ == '__main__': djc.recipe.manage.main('djc_recipe_django.settings')
正如我们所见,manage 模块的 main() 函数被调用,将设置文件作为唯一参数传入。
现在我们可以尝试设置一个示例开发环境,向其中传入 debug = true
>>> write('buildout.cfg', ... """ ... [buildout] ... parts = django ... offline = false ... download-cache = %s ... newest = false ... index = http://pypi.python.org/simple/ ... find-links = packages ... ... [django] ... recipe = djc.recipe ... project = dummydjangoprj ... debug = true ... """ % cache_dir) >>> print "start\n", system(buildout) start ... Installing django. django: Making ... a module django: Generating settings in ... django: Making empty static directory ... django: Creating script at ... Generated script ... <BLANKLINE>
然后看看生成的设置
>>> cat('parts', 'django', 'djc_recipe_django', 'settings.py') # coding=utf-8 SERVER_EMAIL = 'root@localhost' ADMINS = ( <BLANKLINE> ('John Smith', 'root@localhost'), ) MANAGERS = ADMINS <BLANKLINE> <BLANKLINE> DATABASES = {'default': {'ENGINE': 'django.db.backends.sqlite3', 'NAME': '/sample-buildout/storage.db'}} <BLANKLINE> TIME_ZONE = 'America/Chicago' <BLANKLINE> LANGUAGE_CODE = 'en-us' <BLANKLINE> USE_L10N = True <BLANKLINE> STATIC_ROOT = '.../static' <BLANKLINE> STATIC_URL = '/static/' <BLANKLINE> MEDIA_ROOT = '.../media' <BLANKLINE> MEDIA_URL = '/media/' <BLANKLINE> ADMIN_MEDIA_PREFIX = '/admin_media/' <BLANKLINE> SECRET_KEY = '...' <BLANKLINE> ROOT_URLCONF = 'dummydjangoprj.urls' <BLANKLINE> <BLANKLINE> TEMPLATE_DIRS = ( '.../dummydjangoprj/templates', ) <BLANKLINE> EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' EMAIL_USE_TLS = False <BLANKLINE> CACHE_BACKEND = 'locmem:///' CACHE_TIMEOUT = 60*5 CACHE_PREFIX = 'Z' <BLANKLINE> DEBUG = True TEMPLATE_DEBUG = DEBUG <BLANKLINE> INTERNAL_IPS = ( '127.0.0.1', )
模板覆盖
正如在模板化中所述,默认模板可以被覆盖或扩展。
让我们先来扩展它
>>> write('template-extension.py.in', ... """ ... # Here we can extend the template, using variables pulled in from the ... # buildout section, with the dashes converted to underscores ... MY_CONFIG_VARIABLE = '{{config_variable_one}}' ... """) >>> write('buildout.cfg', ... """ ... [buildout] ... parts = django ... offline = false ... download-cache = %s ... newest = false ... index = http://pypi.python.org/simple/ ... find-links = packages ... ... [django] ... recipe = djc.recipe ... project = dummydjangoprj ... settings-template-extension = template-extension.py.in ... config-variable-one = test ... """ % cache_dir)
启动 buildout,然后查看生成的 settings.py 文件
>>> print system(buildout) Uninstalling django. Installing django. ... Generated script ... <BLANKLINE> >>> cat('parts', 'django', 'djc_recipe_django', 'settings.py') # coding=utf-8 SERVER_EMAIL = 'root@localhost' ADMINS = ( <BLANKLINE> ('John Smith', 'root@localhost'), ) MANAGERS = ADMINS <BLANKLINE> <BLANKLINE> DATABASES = {'default': {'ENGINE': 'django.db.backends.sqlite3', 'NAME': '/sample-buildout/storage.db'}} <BLANKLINE> TIME_ZONE = 'America/Chicago' <BLANKLINE> LANGUAGE_CODE = 'en-us' <BLANKLINE> USE_L10N = True <BLANKLINE> STATIC_ROOT = '.../static' <BLANKLINE> STATIC_URL = '/static/' <BLANKLINE> MEDIA_ROOT = '.../media' <BLANKLINE> MEDIA_URL = '/media/' <BLANKLINE> ADMIN_MEDIA_PREFIX = '/admin_media/' <BLANKLINE> SECRET_KEY = '...' <BLANKLINE> ROOT_URLCONF = 'dummydjangoprj.urls' <BLANKLINE> <BLANKLINE> TEMPLATE_DIRS = ( '.../dummydjangoprj/templates', ) <BLANKLINE> EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' EMAIL_USE_TLS = False <BLANKLINE> CACHE_BACKEND = 'locmem:///' CACHE_TIMEOUT = 60*5 CACHE_PREFIX = 'Z' <BLANKLINE> DEBUG = False TEMPLATE_DEBUG = DEBUG <BLANKLINE> <BLANKLINE> # Extension template template-extension.py.in <BLANKLINE> <BLANKLINE> # Here we can extend the template, using variables pulled in from the # buildout section, with the dashes converted to underscores MY_CONFIG_VARIABLE = 'test'
正如你所见,额外的模板简单地追加到了默认模板上,变量 config-variable-one 被替换。
如果我们完全覆盖模板
>>> write('template.py.in', ... """ ... # Total override ... FOODS = ( ... {{join(listify(foods), "',\\n '", "'", "',")}} ... ) ... """) >>> write('buildout.cfg', ... """ ... [buildout] ... parts = django ... offline = false ... download-cache = %s ... newest = false ... index = http://pypi.python.org/simple/ ... find-links = packages ... ... [django] ... recipe = djc.recipe ... project = dummydjangoprj ... settings-template = template.py.in ... foods = ... spam ... spam ... eggs ... spam ... """ % cache_dir)
启动 buildout,然后查看生成的 settings.py 文件
>>> print system(buildout) Uninstalling django. Installing django. ... Generated script ... <BLANKLINE> >>> cat('parts', 'django', 'djc_recipe_django', 'settings.py') # Total override FOODS = ( 'spam', 'spam', 'eggs', 'spam', )
正如你所见,内置模板被完全丢弃。
静态来源
静态文件通常不是通过 Django 服务的,而是前端 Web 服务器负责通过在文件系统中公开目录来提供它们。
然而,许多静态文件(例如 .js 或 .css)是项目或应用功能的一部分,因此能够将它们与代码一起分发将很有趣。
相关资源可以包含在分发的包中,使用 static-origin 选项可以将它们复制到 static-directory 文件夹中(参见 选项)。
对于媒体文件(例如图像上传)也有类似的特性(选项 media-origin,最终会进入 media-directory)。
static-origin 可以包含静态文件源列表,列表中的每个项可以是 package:directory 或 package:directory:destination 的形式;package 是可导入模块的完整点分名称,directory 是包含静态数据的模块内部的路径,destination 是可选的子目录,用于在 static-directory 中复制文件。
那么,让我们从第一个简单的情况开始,只有一个静态数据源。
静态数据源是位于 src 中的开发包 dummydjangoapp1。
>>> ls('src', 'dummydjangoapp1', 'dummydjangoapp1', 'static') - lib1.js - main.css >>> cat('src', 'dummydjangoapp1', 'dummydjangoapp1', 'static', 'main.css') body { font-family: "Helvetica" "Arial" sans-serif; }
让我们创建一个 buildout 配置并运行它
>>> write('buildout.cfg', ... """ ... [buildout] ... parts = django ... offline = false ... download-cache = %s ... newest = false ... index = http://pypi.python.org/simple/ ... find-links = packages ... develop = src/dummydjangoapp1 ... eggs = dummydjangoapp1 ... ... [django] ... recipe = djc.recipe ... project = dummydjangoprj ... static-directory = static ... static-origin = dummydjangoapp1:static ... """ % cache_dir) >>> rmdir('static') >>> print system(buildout) Develop: '.../dummydjangoapp1' Uninstalling django. Installing django. ... django: Making static directory '.../static' ... Generated script ... <BLANKLINE>
现在让我们看看 static 里面有什么
>>> ls('static') - lib1.js - main.css >>> cat('static', 'main.css') body { font-family: "Helvetica" "Arial" sans-serif; }
现在让我们尝试使用两个源:第二个是一个名为 dummydjangoapp2 的另一个虚拟应用程序,它像第一个一样位于 src 中。
让我们看看它的 static 中有什么
>>> ls('src', 'dummydjangoapp2', 'dummydjangoapp2', 'static') - lib2.js - main.css
看起来这个应用程序也定义了 main.css,所以让我们看看内容
>>> cat('src', 'dummydjangoapp2', 'dummydjangoapp2', 'static', 'main.css') h1 { color: #92B8D8; }
但这会带来问题!当我将其作为第二个源时,两个都定义了 main.css 会发生什么?在这里,最直观的做法可能是覆盖文件,以便底部的源是顶部的 皮肤层。
所以如果我们有这个 buildout
>>> write('buildout.cfg', ... """ ... [buildout] ... parts = django ... offline = false ... download-cache = %s ... newest = false ... index = http://pypi.python.org/simple/ ... find-links = packages ... develop = ... src/dummydjangoapp1 ... src/dummydjangoapp2 ... eggs = ... dummydjangoapp1 ... dummydjangoapp2 ... ... [django] ... recipe = djc.recipe ... project = dummydjangoprj ... static-directory = static ... static-origin = ... dummydjangoapp1:static ... dummydjangoapp2:static ... """ % cache_dir)
运行后,可以合理预期< span class="docutils literal">main.css 文件的内容是由< span class="docutils literal">dummydjangoapp2 持有的版本提供的,而不是由< span class="docutils literal">dummydjangoapp2 持有的版本。
快速运行并检查确认了这一点
>>> rmdir('static') >>> print system(buildout) Develop: '.../dummydjangoapp1' Develop: '.../dummydjangoapp2' Uninstalling django. Installing django. ... django: Making static directory '.../static' ... Generated script ... <BLANKLINE> >>> ls('static') - lib1.js - lib2.js - main.css >>> cat('static', 'main.css') h1 { color: #92B8D8; }
然而,我可能不想让< span class="docutils literal">main.css 覆盖发生,或者任何其他应用程序之间的冲突。这很容易通过以下方式编写的构建来完成
>>> write('buildout.cfg', ... """ ... [buildout] ... parts = django ... offline = false ... download-cache = %s ... newest = false ... index = http://pypi.python.org/simple/ ... find-links = packages ... develop = ... src/dummydjangoapp1 ... src/dummydjangoapp2 ... eggs = ... dummydjangoapp1 ... dummydjangoapp2 ... ... [django] ... recipe = djc.recipe ... project = dummydjangoprj ... static-directory = static ... static-origin = ... dummydjangoapp1:static:app1 ... dummydjangoapp2:static:app2 ... """ % cache_dir)
需要注意的是,现在< span class="docutils literal">static-origin 值有三个元素,最后一个元素是目标目录,它被定义为< span class="docutils literal">static 的子目录:在这种情况下,两个应用程序都位于它们的子目录中,没有发生冲突
>>> rmdir('static') >>> print system(buildout) Develop: '.../dummydjangoapp1' Develop: '.../dummydjangoapp2' Uninstalling django. Installing django. ... django: Making static directory '.../static' ... Generated script ... <BLANKLINE> >>> ls('static') d app1 d app2 >>> ls('static', 'app1') - lib1.js - main.css >>> cat('static', 'app1', 'main.css') body { font-family: "Helvetica" "Arial" sans-serif; } >>> ls('static', 'app2') - lib2.js - main.css >>> cat('static', 'app2', 'main.css') h1 { color: #92B8D8; }
当然,这种行为不仅在这个情况下有用:应用程序可能实际上需要您将静态文件放置在精确的子目录中,无论其他应用程序是否存在或发生冲突。
WSGI
< span class="docutils literal">wsgi 选项将在< span class="docutils literal">parts 中创建一个小的模块< a href="#footnote-3" id="footnote-reference-3" rel="nofollow">< span class="fn-bracket">[ 3< span class="fn-bracket">] ,这将允许您将您的应用程序连接到上游< span class="docutils literal">wsgi 服务器。
为了有构建,我们必须将配方中的< span class="docutils literal">wsgi 选项设置为< span class="docutils literal">true
>>> write('buildout.cfg', ... """ ... [buildout] ... parts = django ... offline = false ... download-cache = %s ... newest = false ... index = http://pypi.python.org/simple/ ... find-links = packages ... ... [django] ... recipe = djc.recipe ... project = dummydjangoprj ... wsgi = true ... """ % cache_dir)
并启动构建
>>> print "start\n", system(buildout) start ... Installing django. ... django: Generating settings in ... ... django: Creating script at .../bin/django Generated script '.../bin/django'. django: Creating script at .../parts/django/djc_recipe_django/app.py Generated script '.../parts/django/djc_recipe_django/app.py'. <BLANKLINE>
然后,脚本将在< span class="docutils literal">parts/<part_name>/djc_recipe_<part_name> 内创建一个包含< span class="docutils literal">app.py 文件的 Python 模块,该模块可以被 < span class="docutils literal">Apache 或 < span class="docutils literal">uwsgi 加载
>>> ls('parts', 'django', 'djc_recipe_django') - __init__.py - app.py - settings.py >>> cat('parts', 'django', 'djc_recipe_django', 'app.py') #!... <BLANKLINE> <BLANKLINE> import sys sys.path[0:0] = [ ... ] <BLANKLINE> import djc.recipe.wsgi <BLANKLINE> application = djc.recipe.wsgi.main('djc_recipe_django.settings') <BLANKLINE> def app_factory(global_config, **local_config): """This function wraps our simple WSGI app so it can be used with paste.deploy""" return application
这将负责将所有必需的路径注入 < span class="docutils literal">sys.path,因此不需要进一步干预。
大多数 < em> WSGI 服务器都会自行有效地处理日志记录,但是如果没有,可以使用单独的日志输出选项:如果设置,将导致所有应用程序日志输出写入指定的文件:< span class="docutils literal">wsgi-logfile
让我们编写构建
>>> write('buildout.cfg', ... """ ... [buildout] ... parts = django ... offline = false ... download-cache = %s ... newest = false ... index = http://pypi.python.org/simple/ ... find-links = packages ... ... [django] ... recipe = djc.recipe ... project = dummydjangoprj ... wsgi = true ... wsgi-logfile = wsgi.log ... """ % cache_dir)
启动它
>>> print "start\n", system(buildout) start ... Installing django. ... django: Generating settings in ... ... django: Creating script at .../bin/django Generated script '.../bin/django'. django: Creating script at .../parts/django/djc_recipe_django/app.py Generated script '.../parts/django/djc_recipe_django/app.py'. <BLANKLINE>
并检查更改
>>> cat('parts', 'django', 'djc_recipe_django', 'app.py') #!... <BLANKLINE> <BLANKLINE> import sys sys.path[0:0] = [ ... ] <BLANKLINE> import djc.recipe.wsgi <BLANKLINE> application = djc.recipe.wsgi.main(..., logfile = '.../wsgi.log') <BLANKLINE> def app_factory(global_config, **local_config): """This function wraps our simple WSGI app so it can be used with paste.deploy""" return application
如您所见,日志文件参数传递给应用程序:请注意,所有相对路径都是相对于构建根的相对路径。
自定义初始化
有时我们需要在管理脚本和 WSGI 应用程序中添加一些特定的初始化代码,或者在该过程中设置某些环境变量,而无需使用神秘配置。
第一个需求通过 < span class="docutils literal">initialization 选项得到解决:假设我们希望我们的管理和 WSGI 脚本在启动之前检查一个整数是否真的是整数(因此,如果世界已经颠倒,可以安全地终止)。
我们将编写我们的构建
>>> write('buildout.cfg', #doctest:-NORMALIZE_WHITESPACE ... """ ... [buildout] ... parts = django ... offline = false ... download-cache = %s ... newest = false ... index = http://pypi.python.org/simple/ ... find-links = packages ... ... [django] ... recipe = djc.recipe ... project = dummydjangoprj ... wsgi = true ... initialization = ... >>> if not isinstance(1, int): ... ... raise TypeError("World has turned upside down") ... """ % cache_dir)
并启动它
>>> print "start\n", system(buildout) start ... Installing django. ... django: Generating settings in ... ... django: Creating script at .../bin/django Generated script '.../bin/django'. django: Creating script at .../parts/django/djc_recipe_django/app.py Generated script '.../parts/django/djc_recipe_django/app.py'. <BLANKLINE>
并看到我们的代码在 < span class="docutils literal">bin/django 和 < span class="docutils literal">app.py 中都存在
>>> cat('bin', 'django') #doctest:-NORMALIZE_WHITESPACE #!... <BLANKLINE> import sys sys.path[0:0] = [ ... ] <BLANKLINE> <BLANKLINE> <BLANKLINE> if not isinstance(1, int): raise TypeError("World has turned upside down") <BLANKLINE> <BLANKLINE> import djc.recipe.manage <BLANKLINE> if __name__ == '__main__': djc.recipe.manage.main('djc_recipe_django.settings') >>> cat('parts', 'django', 'djc_recipe_django', 'app.py') #doctest:-NORMALIZE_WHITESPACE #!... <BLANKLINE> <BLANKLINE> import sys sys.path[0:0] = [ ... ] <BLANKLINE> <BLANKLINE> if not isinstance(1, int): raise TypeError("World has turned upside down") <BLANKLINE> <BLANKLINE> import djc.recipe.wsgi <BLANKLINE> application = djc.recipe.wsgi.main('djc_recipe_django.settings') <BLANKLINE> def app_factory(global_config, **local_config): """This function wraps our simple WSGI app so it can be used with paste.deploy""" return application
需要注意的是,Python 代码的第一行前面加上了 < span class="docutils literal">>>>,而所有后续行都加上了 < span class="docutils literal">...(加一个空格,在两边)。如果想要保留缩进,则必须使用此语法:如果不想使用,则可以省略它们,但必须确保< em>永远不要有结构。
一个更有用的例子是需要设置特定的环境变量,在 django 初始化之前,例如,有人可能想要将 < span class="docutils literal">GOOGLE_APPENGINE_PROJECT_ROOT 设置为 < span class="docutils literal">/my/path。
为了做到这一点,可以使用 < span class="docutils literal">environment-vars 选项:
>>> write('buildout.cfg', ... """ ... [buildout] ... parts = django ... offline = false ... download-cache = %s ... newest = false ... index = http://pypi.python.org/simple/ ... find-links = packages ... ... [django] ... recipe = djc.recipe ... project = dummydjangoprj ... wsgi = true ... environment-vars = ... GOOGLE_APPENGINE_PROJECT_ROOT /my/path ... """ % cache_dir)
启动构建
>>> print "start\n", system(buildout) start ... Installing django. ... django: Generating settings in ... ... django: Creating script at .../bin/django Generated script '.../bin/django'. django: Creating script at .../parts/django/djc_recipe_django/app.py Generated script '.../parts/django/djc_recipe_django/app.py'. <BLANKLINE>
请确保环境变量初始化代码(通过 os.environ)存在于 bin/django 和 app.py 中。
>>> cat('bin', 'django') #!... <BLANKLINE> import sys sys.path[0:0] = [ ... ] <BLANKLINE> <BLANKLINE> <BLANKLINE> import os os.environ["GOOGLE_APPENGINE_PROJECT_ROOT"] = r"/my/path" <BLANKLINE> <BLANKLINE> import djc.recipe.manage <BLANKLINE> if __name__ == '__main__': djc.recipe.manage.main('djc_recipe_django.settings') >>> cat('parts', 'django', 'djc_recipe_django', 'app.py') #!... <BLANKLINE> <BLANKLINE> import sys sys.path[0:0] = [ ... ] <BLANKLINE> <BLANKLINE> <BLANKLINE> import os os.environ["GOOGLE_APPENGINE_PROJECT_ROOT"] = r"/my/path" <BLANKLINE> <BLANKLINE> import djc.recipe.wsgi <BLANKLINE> application = djc.recipe.wsgi.main('djc_recipe_django.settings') <BLANKLINE> def app_factory(global_config, **local_config): """This function wraps our simple WSGI app so it can be used with paste.deploy""" return application
贡献者
Simone Deponti <simone.deponti@abstract.it>,初始作者
Bruno Ripa <bruno.ripa@abstract.it>
Mikko Ohtamaa (@moo9000)
Dimitri Roche
由 Abstract Open Solutions 赞助的初始开发
变更历史
0.9.7 (2012-07-02)
使 SETTINGS_NAME 可配置 [Simone Deponti]
使多项内容更加符合 Pythonic [Simone Deponti]
弃用了某个版本 [Simone Deponti]
0.9.6 (2012-02-10)
向默认模板添加了 use-l10n 选项 [Simone Deponti]
0.9.5 (2012-01-12)
修复了媒体目录删除错误 [Simone Deponti]
0.9.4 (2012-01-03)
修复了在删除链接树时复制的另一个错误 [Simone Deponti]
0.9.3 (2012-01-02)
修复了静态目录复制错误 [Simone Deponti]
0.9.2 (2011-12-23)
添加了静态和原始的“智能”符号链接 [Simone Deponti]
0.9.1 (2011-12-13)
修复了 reST 的烦恼 [Simone Deponti]
0.9 (2011-12-13)
为初始化代码添加了缩进保留功能 [Simone Deponti]
添加了表示数据库的新默认方式 [Simone Deponti]
添加了引用其他部分的能力 [Simone Deponti]
使 'settings.py' 可导入。 [Simone Deponti]
加快了测试速度。 [Simone Deponti]
0.8.1 (2011-09-22)
修复了 MANIFEST.in [Simone Deponti]
0.8 (2011-09-22)
重构了环境变量支持 [Simone Deponti]
添加了初始化支持 [Simone Deponti]
修复了文档并添加了测试 [Simone Deponti]
0.7.4 (2011-09-15)
更改了存储库位置 [Simone Deponti]
使 DEBUG 明确 [Simone Deponti]
修复了 Windows 上的路径 [Dimitri Roche]
0.7.3 (2011-03-30)
添加了环境变量支持 [Mikko Ohtamaa]
0.7.2 (2010-11-18)
修复了日志记录并添加了 loglevel [Simone Deponti]
0.7.1 (2010-09-23)
修复了多个链接错误 [Simone Deponti]
0.7 (2010-09-23)
添加了静态原始符号链接的能力 [Simone Deponti]
重构了工作集计算以获得更好的性能 [Simone Deponti]
0.6.1 (2010-07-22)
修复了编码错误。 [Simone Deponti]
0.6 (2010-07-20)
添加了新的邮件设置,并重构了默认设置。 [Simone Deponti]
添加了对多个数据库和新式数据库设置的 support [Simone Deponti]
修复了测试和文档中的错误。 [Simone Deponti]
0.5.1 (2010-06-07)
使 wsgi 模块更符合 paster 兼容性
0.5 (2010-06-03)
注意
本版本可能不向后兼容:现在 media-url 和 media-directory 分别命名为 static-url 和 static-directory。
修复了 MEDIA_URL 的问题 [Simone Deponti]
添加了对 INTERNAL_IPS 的 support [Simone Deponti]
中间件、模板加载器和应用的默认设置已取消 [Simone Deponti]
0.3.2 (2010-06-01)
修复了 WSGI 支持(uwsgi,自定义记录器) [Simone Deponti]
修复了导入错误 [Simone Deponti]
0.3.1 (2010-05-19)
又名“永远不在午夜到早上6点之间发布”
修复了默认模板中 fixture 目录的绝对路径错误 [Simone Deponti]
修复了小的模板扩展错误 [Simone Deponti]
0.3 (2010-05-19)
添加了对多个媒体源的支持 [Simone Deponti]
添加了对 fixture-dirs 的支持 [Simone Deponti]
0.2 (2010-05-17)
第一个公开版本 [Simone Deponti]
0.1 (2010-04-22)
创建了包 [Simone Deponti]
项目详情
djc.recipe-0.9.7.zip 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 4edd3c81c5cd0f03551ffabe7bdcef442a55226068a2ff11491f732ecea5b379 |
|
MD5 | c5d5873934a3018766f080ac8a0a2a8b |
|
BLAKE2b-256 | 1307af80facc97c0a2731e0e0be8cc8054ad761ccca06e69bf10628695925feb |