Package: djc.recipe
ContentsUsageRunning testsLinksDetailed DocumentationOptionsAdvanced optionsTemplatingFunctionsDefault template optionsDeprecated optionsExample usageTemplate overridingStatic originWSGICustom initializationContributorsChange history0.9.7 (2012-07-02)0.9.6 (2012-02-10)0.9.5 (2012-01-12)0.9.4 (2012-01-03)0.9.3 (2012-01-02)0.9.2 (2011-12-23)0.9.1 (2011-12-13)0.9 (2011-12-13)0.8.1 (2011-09-22)0.8 (2011-09-22)0.7.4 (2011-09-15)0.7.3 (2011-03-30)0.7.2 (2010-11-18)0.7.1 (2010-09-23)0.7 (2010-09-23)0.6.1 (2010-07-22)0.6 (2010-07-20)0.5.1 (2010-06-07)0.5 (2010-06-03)0.3.2 (2010-06-01)0.3.1 (2010-05-19)0.3 (2010-05-19)0.2 (2010-05-17)0.1 (2010-04-22)WarningThis recipe has been deprecated in favor ofdjc.recipe2.
If you are starting a new project,don’t use this package,
usedjc.recipe2.
This package might see minor bug fixes to keep existing buildouts running,
but it won’t gain new features.This recipe allows you to setup aDjangoproject throughzc.buildout.UsageThe main scope of the recipe is to abstract out thesettings.pyfile,
allowing settings to reside inside the buildout instead of having them reside
into code (leading to an awkard handling of the same in respect to versioning,
for example). Thesettings.pyfile is generated by a template, either the
default one, the default one and a user extension, or a totally new one.The template uses theTempitatemplating system.The most basic usage of this recipe is as follows:[buildout]
parts = django

[django]
recipe = djc.recipe
project = my.projectWheremy.projectis an importable package containing aurlsmodule and
atemplatesdirectory.As you see, very few options are specified here: the defaults are used to build
up thesettings.pyfile.Of course, real examples tend to be slightly more complex: seeOptions,Default template optionsandExample usagefor more details.Running testsTheREADME.txtlocated within the package also acts as main doctest.To run the tests, check out the source, and then bootstrap and run the buildout:$ python bootstrap.py
$ bin/buildoutThen you can run the tests using:$ bin/testLinksCode repository:http://github.com/abstract-open-solutions/djc.recipeDiscussions athttps://groups.google.com/group/djcrecipeComments and questions atinfo@abstract.itDetailed DocumentationOptionsThe options of this recipe are not fixed, as many of those are used exclusively
within the settings template file (seeTemplating).Here we present the options that have an impact on the recipe aswell:projectThis identifies a python module (in dotted notation) that can serve as
project package. The bare minimum for a project package is to contain aurls.pyfile and atemplatesdirectory. It is mandatory unless both
theurlconfandtemplatesoption are defined.urlconfIdentifies the module that contains the url definition: if omitted the fileurls.pyinside the module given asprojectis used.templatesIdentifies the templates directory. If omitted, the directory namedtemplateslocated in the module given asprojectis used.static-directoryIdentifies the folder into which static content (images, CSS and
Javascripts) will go. Relatives path are considered relative to the
buildout directory. The directory will be created if not present, and
nothing will be done if it already exists. If omitted, defaults tostatic.media-directoryIdentifies the folder into which uploaded files will go. If omitted,
defaults tomedia.settings-templateIf specified, the given template is used to generate thesettings.pyfile, if not provided, the default template will be used. SeeTemplatingfor more details.settings-template-extensionIf specified, the given template is appended to the template specified bysettings templateor to the default one.static-originIf specified, defines directories from which to copy the static files that
have to go instatic-directory: seeStatic originfor more details.link-static-originBoolean value, defaults tofalse. If set, the files will be symlinked
instead of copied. Does work only on unix.media-originIf specified, defines directories from which to copy the data files that
have to go inmedia-directory: seestatic-originoption for
details.base-settingsA settings module (only absolute imports) that is extended by the current
settings, for examplemy.module.settings.
If specified, the defaults forapps,middlewareandtemplate-loadersbecomes an empty string (resulting into them not being
written at all).
It is unset by default.wsgiDefaults tofalse. If set totrue(oronor1) creates a
script inparts/$partnamenamed$partname.wsgi.pythat can be used
as WSGI script in Apache or other WSGI enabled webserver.wsgi-logfileIf set, the log will be redirected here: defaults to not being set.wsgi-loglevelSets the log level: it is only processed ifwsgi-loglevelis also set.
The accepted values are:debug,info,warning,error,criticalcodingThe encoding of the resulting settings file. Defaults toutf-8.Advanced optionsNoteAll these options are optional and should not be necessary under
normal conditions, but might be useful to advanced users.The following advanced options are supported:extra-pathsA number of non-standard paths where additional python modules are located.pth-filesA number of pth-files from which to load additional python modulesthat
should be present in the buildout.initializationAllows extra python code to be added to both the manage and theWSGIscript: seeCustom initializationfor more details.environment-varsAllows one to override OS environment vars by setting them duringmanage.pyrun. One environment variable name and value per line, space
separated.  Variable values can be hardcoded or buildout template mechanism
can be used where you refer to other variables set in buildout.Example:environment-vars =
        GOOGLE_APPENGINE_PROJECT_ROOT ${buildout:appengine-base-path}
        TZ Europe/HelsinkiYou might want to also checkgocept.recipe.envbuildout recipe if you
wish to extend existing environment variables, likePATH.
SeeCustom initializationfor more details and an example.TemplatingThesettings.pyfile is generated by interpolating the options of the
buildout section with a template, be it the default one or the one provided by
thesettings-templateoption.The template must be a validTempitatemplate, to which the whole options of
the current buildout section is passed as namespace, integrated as follow:In the options name, all minuses (-) are converted to underscores
(_)The optionnameandsecretare added, respectively mapping to the
buildout section name and to a randomly-generated secret[1].A serie of functions is added to the namespace to simplify the handling of
some situations, see below for more details.FunctionsA certain number of functions can be used inside the templates:absolute_urlTakes a path and, if it is relative, concatenates it with the buildout
location to make it absolute.listifyTakes a chunk of data, splits it into lines, trims those lines and returns
the obtained list, from which void strings are purged.rfc822tuplizeThis function is quite specialized and takes any string in the formFull Name <email.address@example.com>into a tuple composed by the full
name and the mail address. It will return a tuple with the unchanged data
if the data fed in does not conform to the specifics.boolifyThis functions returnsTrueif the data fed is is any oftrue,on,1(case- insensitive) andFalseotherwisejoinEquivalent of string’sjoin()method, with the data to join as first
parameter, theinfixas second and two optional parametersprefix(added just one to the beginning) andsuffix(added just one to the end)dumpAn alias ofrepr.Default template optionsThe default template accepts a number of options. They are to be considered all
optional, as sensible defaults will be provided if omitted.databaseThe settings of the default Django database, in the formengine=<backend>(user=<user>password=<password>)(host=<host>)(port=<port>)name=<name>(options=(<options>)).
Parenthesized values are to be considered as optional.  It is to be noted
that the options are expected to be enclosed within parentesis ((),
separated by comma and in the form<name>=<value>.
An example url might be:engine=django.db.backends.mysql user=usr password=pwd host=localhost port=3306 name=mydboptions=(opt1=val1,opt2=val2)whereusr,pwd,mydbetc should be replaced by your
configuration values.
Defaults toengine=django.db.backends.sqlite3name=/${buildout:directory}/storage.dbNoteThe old url-like format is still functioning but is currently
deprecated and might be removed in the future.additional-databasesA list of databases in the formname=parameters, each on one line,
wherenameis the Django-internal database name andparametersis
the database settings in the same form as that provided bydatabasemedia-urlThe static content prefix path. Defaults tomediaadmin-mediaThe admin only static content prefix path. Defaults toadmin_mediatimezoneThe timezone: defaults toAmerica/Chicagolanguage-codeThe language code: defaults toen-ususe-l10nWhether to usel10nor not: defaults totrueserver-mailThe email address from which site-generate mails come from. Defaults toroot@localhostadminsThe list of site admins, inRFC822form. Defaults toJohn Smith <root@localhost>managersThe list of managers: same as foradmins. Defaults to copy the value ofadminsmiddlewareThe list of middleware classes to load. If an empty string, the value is
not written at all.appsThe list of apps to load. If empty, the value is not written at all.template-loadersThe list of template loaders to use. If empty, the value is not written at
all.debugIftrue, activates debug mode. Defaults tofalseinternal-ipsThe IPs that are allowed to see full stack traces when in debug. Defaults
to127.0.0.1site-idThe Django site id. Defaults to unset.template-context-processorsThe Django template context processors. Defaults to unset.authentication-backendsThe Django authentication backends. Defaults to unsetlanguagesA list of supported languages in the formcode Fullname, for exampleen-usEnglish (US). Defaults to unset.mail-backendThe mail backend to use. Defaults todjango.core.mail.backends.smtp.EmailBackend.mail-filepathThe directory to use if the file mail backend is used[2].smtp-hostThe SMTP host to use when sending mail. Defaults to unset.smtp-portThe SMTP server port. Defaults to unset.smtp-userThe username to use to connect to the SMTP server. Defaults to unset.smtp-passwordThe password to use to connect to the SMTP server. This is not valid ifsmtp-useris not set aswell. Defaults to unset.smtp-tlsWhether TLS should be used when connecting to the SMTP server (boolean
option). Defaults tofalse.site-domainThe site domain. Defaults to unset.site-nameThe site title. Defaults to unset.cache-backendThe cache backend. Defaults tolocmem:///.cache-timeoutThe cache timeout in seconds. Defaults to60*5.cache-prefixThe cache prefix (prefixed at all cache IDs). Defaults toZ.fixture-dirsThe directories into which search for fixtures. Not set by default.Deprecated optionsThese options are still supported within templates, but they are pending
deletion.database-engineThe database engine to use.database-nameThe name of the database to use.database-userThe username to use when connecting to the database server. Defaults to
empty string.database-passwordThe password to use when connecting to the database server. Defaults to
empty string.database-hostThe host on which the database server resides. Defaults to empty string.database-portThe port on which the database server accepts connections. Defaults to
empty string.Example usageAs first thing, we need to have a Django project egg around. We have made a
very simple one just for testing and we have created a source distribution for
it located inpackages.This is of course not the only way you can distribute and obtain the project
egg: for example, during developement, it is recommended to usemr.developerfor that.That cleared, we create the most simple buildout conceivable using this recipe>>> 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)And run it>>> 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>This generated some files and directories for us:A Djangomanage.pywrapper located atbin/djangoA media directory (empty) atstatic(default option)A settings file located inparts/django/djc_recipe_django/settings.pySo, as we can see, we have astaticdirectory in the root, abin/djangoscript and aparts/djangopart>>> 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  djangoLet’s look at this first>>> ls('parts', 'django')
d  djc_recipe_django
>>> ls('parts', 'django', 'djc_recipe_django')
-  __init__.py
-  settings.pyTherefore, we can see howdjc_recipe_djangois actually an importable
python module.If we examine it:>>> 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 = DEBUGAs you can see, this is pretty much the standard Djangosettings.pyas
created by Django’sdjango-admin. It has the peculiarity of not residing in
a module, however, but is loaded at run time into the appropriate manage script
as aghostmodule named_django_settings.Let’s have a look at the manage script>>> 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')As we can see, themain()function of themanagemodule is called,
passing in the file with the settings as only argument.We can now try to set up an example development environment, passingdebug = trueto it:>>> 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>And look at the generated settings:>>> 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',
)Template overridingAs it was said inTemplating, the default template can be overridden or
extended.Let’s start by extending it:>>> 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)Launch the buildout and then take a look at the generatedsettings.pyfile>>> 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'As you can see, the aditional template has been simply appended to the default,
and the variableconfig-variable-onehas been substituted.If, instead, we totally override the template:>>> 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)Launch the buildout and then take a look at the generatedsettings.pyfile>>> 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',
)As you can see, the builtin template has been totally discarded.Static originStatic files are generally not served throughDjango, but instead the
front-end web server takes care to serve them by exposing a directory on the
filesystem to the web.However, many static files (think.jsor.css) are part of the
functionality of a project or application, and would be interesting to be able
to distribute them alongside the code.NoteThe method here described works only for applications and packages
that are not installed as zipped modules: for example the egg default format
is a zipped file that does not get extracted after installation unless a
proper option is passed toeasy_installThe relevant resources can be included in the distributed package and use of
thestatic-originoption will allow them to be copied into thestatic-directoryfolder (seeOptions).A similar feature is present for media files (e.g. image uploads) as well
(optionmedia-origin, which ends up intomedia-directory).static-origincan contain a list of static file sources, and each item of
the list can be either in the formpackage:directoryorpackage:directory:destination;packagebeing the full dotted name of
the importable module,directorythe path to the directory inside the
module containing static data, anddestinationan optional subdirectory
insidestatic-directorywhere to copy the files.Let’s then begin from the first, simple case, with a single source of static
data.The source of static data is the packagedummydjangoapp1, residing as a
developement package insidesrc.>>> ls('src', 'dummydjangoapp1', 'dummydjangoapp1', 'static')
-  lib1.js
-  main.css
>>> cat('src', 'dummydjangoapp1', 'dummydjangoapp1', 'static', 'main.css')
body { font-family: "Helvetica" "Arial" sans-serif; }Let’s create a buildout config and run it>>> 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>And now let’s see what’s instatic>>> ls('static')
-  lib1.js
-  main.css
>>> cat('static', 'main.css')
body { font-family: "Helvetica" "Arial" sans-serif; }Let’s now try usingtwosources: the second is another dummy app, nameddummydjangoapp2, that like the first one resides insrc.Let’s see what’s in itsstaticfor us:>>> ls('src', 'dummydjangoapp2', 'dummydjangoapp2', 'static')
-  lib2.js
-  main.cssIt seems this app too defines amain.css, so let’s look at the content:>>> cat('src', 'dummydjangoapp2', 'dummydjangoapp2', 'static', 'main.css')
h1 { color: #92B8D8; }But this poses a problem! What happens when I put this as second source, and
both definemain.css? Well, the intuitive thing to do here is probably to
override the file, so that the source at the bottom is the topskin layer.So if we have this 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)It is reasonable to expect that, after running it, the content of themain.cssfile is the one provided by the version held bydummydjangoapp2rather than the one held bydummydjangoapp2.A quick run and inspect confirms this:>>> 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; }However, I might not want themain.cssoverride to happen, or any other
clash between applications, for that matter. That is easily solved by a
buildout written like this>>> 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)It is to be noticed that thestatic-originvalues have now three elements,
the latter being the destination directory, which is defined as a subdirectory
ofstatic: in this case, both apps live in their subdirectory and no clash
happens>>> 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; }Of course, this behaviour is not usefol only in this case: an application might
actually require you to put the static files in a precise subdirectory
irrespective of the fact that other apps might be present or a clash occur.WSGIThewsgioption will create a small module[3]insideparts, that will
allow you to hook your application to an upstreamwsgiserver.In order to have thebuildout, we must set thewsgioption of the
recipe totrue:>>> 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)And launch the buildout:>>> 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>The script will then create insideparts/<part_name>/djc_recipe_<part_name>a python module containing anapp.pyfile, which can be loaded byApacheoruwsgi:>>> 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 applicationThis will take care to inject all the needed paths intosys.path, so no
further meddling should be needed.MostWSGIservers do handle logging effectively by themselves, however if
this was not the case, an option to have a separate log output can be used:wsgi-logfile, if set, will cause all the applicative log output to be
written to the specified file.Let’s write the 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
... wsgi = true
... wsgi-logfile = wsgi.log
... """ % cache_dir)Launch it>>> 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>And check what changes>>> 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 applicationAs you can see, the log file parameter is passed to the application: it is to
be noted that all relative paths are intended as relative to the buildout root.Custom initializationSometimes we have the need to add some particular initialization code to both
the manage script and theWSGIapplication, or have certain environment
variables set in that process without recurring to esoteric configuration.The first need is resolved by theinitializationoption: suppose we want
our manage andWSGIscripts to check that an integer is really an integer
before starting (hence safely aborting if the world has turned upside down).We would write our buildout:>>> 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)And launch it:>>> 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>And see that our code is present in bothbin/djangoandapp.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 applicationIt is important to note that the first line of the python code was prepended
with>>>while all the subsequent lines were prepended with...(plus a
space, on both). This syntax is necessary if you want to preserve indentation:
if you don’t want, you can omit them but you must make sure tonever have
constructs.A slightly more useful example would be the need to have special environment
variables set before django is initialized, for example one might want to setGOOGLE_APPENGINE_PROJECT_ROOTto/my/path.In order to do so, theenvironment-varsoption is used:::>>> 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)The buildout is launched:>>> 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>And see that environment variables initialization code is present (viaos.environ) in bothbin/djangoandapp.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[1]In all truth, it tries to read it from.secret.txt: that failing the
secret code is generated and written to said file to be used
subsequently.[2]For further information, refer to Django’s docs athttp://docs.djangoproject.com/en/1.3/ref/settings/#email-file-path[3]The small module is needed becauseuwsgiwill refuse to load a rogue
script, but will load a module (hence, with somePYTHONPATHmagic,
all comes along)ContributorsSimone Deponti <simone.deponti@abstract.it>, Initial AuthorBruno Ripa <bruno.ripa@abstract.it>Mikko Ohtamaa (@moo9000)Dimitri RocheInital developement sponsored byAbstract Open SolutionsChange history0.9.7 (2012-07-02)Made SETTINGS_NAME configurable [Simone Deponti]Made several things more pythonic [Simone Deponti]Deprecated the version [Simone Deponti]0.9.6 (2012-02-10)Addeduse-l10noption to default template [Simone Deponti]0.9.5 (2012-01-12)Fixed media directory deletion bug [Simone Deponti]0.9.4 (2012-01-03)Fixed another bug with the copier when removing linked trees [Simone Deponti]0.9.3 (2012-01-02)Fixed bug with static directory copying [Simone Deponti]0.9.2 (2011-12-23)Added proper “smart” symlinking of static and origin [Simone Deponti]0.9.1 (2011-12-13)Fixed reST annoyance [Simone Deponti]0.9 (2011-12-13)Added indentation preservation for initialization code. [Simone Deponti]Added a new default way to express databases [Simone Deponti]Added the ability to reference other sections. [Simone Deponti]Made ‘settings.py’ importable. [Simone Deponti]Sped up tests. [Simone Deponti]0.8.1 (2011-09-22)Fixed MANIFEST.in [Simone Deponti]0.8 (2011-09-22)Refactored environment variables support [Simone Deponti]Added initialization support [Simone Deponti]Fixed documentation and added tests [Simone Deponti]0.7.4 (2011-09-15)Changed repository location [Simone Deponti]Made DEBUG explicit [Simone Deponti]Fixed paths on Windows [Dimitri Roche]0.7.3 (2011-03-30)Added environment-variables support [Mikko Ohtamaa]0.7.2 (2010-11-18)Fixed logging and added loglevel [Simone Deponti]0.7.1 (2010-09-23)Fixed multiple link bug [Simone Deponti]0.7 (2010-09-23)Added ability to symlink the static origin [Simone Deponti]Refactored working set computation to achieve better
performances [Simone Deponti]0.6.1 (2010-07-22)Fixed encoding bug. [Simone Deponti]0.6 (2010-07-20)Added new mail settings, restructured defaults. [Simone Deponti]Added support for multiple databases and new-style database settings.
[Simone Deponti]Fixed bugs in the tests and documentation. [Simone Deponti]0.5.1 (2010-06-07)Made the wsgi module more paster-compatible0.5 (2010-06-03)NoteThis release is potentially backwards-incompatible:media-urlandmedia-directoryare now namedstatic-urlandstatic-directoryrespectively.Fixed MEDIA_URL mess [Simone Deponti]Added INTERNAL_IPS support [Simone Deponti]No defaults for middleware, template loaders and apps [Simone Deponti]0.3.2 (2010-06-01)Fixed WSGI support (uwsgi, custom loggers) [Simone Deponti]Fixed import bugs [Simone Deponti]0.3.1 (2010-05-19)aka “Never release between midnight and 6am”:Fixed absolute path bug for fixture dirs in default template [Simone Deponti]Fixed small template extension bug [Simone Deponti]0.3 (2010-05-19)Added multiple media-origin support [Simone Deponti]Added fixture-dirs support [Simone Deponti]0.2 (2010-05-17)First public release [Simone Deponti]0.1 (2010-04-22)Created package [Simone Deponti]