The starter files generated by the zodb
scaffold are basic, but they provide a good orientation for the high-level patterns common to most traversal
-based Pyramid
(and ZODB
based) projects.
The source code for this tutorial stage can be browsed via http://github.com/Pylons/pyramid/tree/1.3-branch/docs/tutorials/wiki/src/basiclayout/.
A directory on disk can be turned into a Python package
by containing an __init__.py
file. Even if empty, this marks a directory as a Python package. Our application uses __init__.py
as both a package marker, as well as to contain application configuration code.
When you run the application using the pserve
command using the development.ini
generated config file, the application configuration points at a Setuptools entry point described as egg:tutorial
. In our application, because the application's setup.py
file says so, this entry point happens to be the main
function within the file named __init__.py
:
src/basiclayout/tutorial/__init__.py
- Lines 1-3. Perform some dependency imports.
- Lines 6-8 Define a root factory for our Pyramid application.
- Line 14. We construct a
Configurator
with aroot factory
and the settings keywords parsed byPasteDeploy
. The root factory is namedroot_factory
. - Line 15. Register a 'static view' which answers requests which start with URL path
/static
using thepyramid.config.Configurator.add_static_view method
. This statement registers a view that will serve up static assets, such as CSS and image files, for us, in this case, athttp://localhost:6543/static/
and below. The first argument is the "name"static
, which indicates that the URL path prefix of the view will be/static
. The second argument of this tag is the "path", which is a relativeasset specification
, so it finds the resources it should serve within thestatic
directory inside thetutorial
package. The scaffold could have alternately used an absolute asset specification as the path (tutorial:static
) but it does not. - Line 16. Perform a
scan
. A scan will findconfiguration decoration
, such as view configuration decorators (e.g.@view_config
) in the source code of thetutorial
package and will take actions based on these decorators. We don't pass any arguments to~pyramid.config.Configurator.scan
, which implies that the scan should take place in the current package (in this case,tutorial
). The scaffold could have equivalently saidconfig.scan('tutorial')
but it chose to omit the package name argument. - Line 17. Use the
pyramid.config.Configurator.make_wsgi_app
method to return aWSGI
application.
Pyramid
uses the word resource
to describe objects arranged hierarchically in a resource tree
. This tree is consulted by traversal
to map URLs to code. In this application, the resource tree represents the site structure, but it also represents the domain model
of the application, because each resource is a node stored persistently in a ZODB
database. The models.py
file is where the zodb
scaffold put the classes that implement our resource objects, each of which happens also to be a domain model object.
Here is the source for models.py
:
src/basiclayout/tutorial/models.py
- Lines 4-5. The
MyModel
resource
class is implemented here. Instances of this class will be capable of being persisted inZODB
because the class inherits from thepersistent.mapping.PersistentMapping
class. The__parent__
and__name__
are important parts of thetraversal
protocol. By default, have these asNone
indicating that this is theroot
object. Lines 8-14.
appmaker
is used to return the application root object. It is called on every request to thePyramid
application. It also performs bootstrapping by creating an application root (inside the ZODB root object) if one does not already exist. It is used by the "root_factory" we've defined in our__init__.py
.We do so by first seeing if the database has the persistent application root. If not, we make an instance, store it, and commit the transaction. We then return the application root object.
Our scaffold generated a default views.py
on our behalf. It contains a single view, which is used to render the page shown when you visit the URL http://localhost:6543/
.
Here is the source for views.py
:
src/basiclayout/tutorial/views.py
Let's try to understand the components in this module:
- Lines 1-2. Perform some dependency imports.
Line 5. Use the
pyramid.view.view_config
configuration decoration
to perform aview configuration
registration. This view configuration registration will be activated when the application is started. It will be activated by virtue of it being found as the result of ascan
(when Line 14 of__init__.py
is run).The
@view_config
decorator accepts a number of keyword arguments. We use two keyword arguments here:context
andrenderer
.The
context
argument signifies that the decorated view callable should only be run whentraversal
finds thetutorial.models.MyModel
resource
to be thecontext
of a request. In English, this means that when the URL/
is visited, becauseMyModel
is the root model, this view callable will be invoked.The
renderer
argument names anasset specification
oftemplates/mytemplate.pt
. This asset specification points at aChameleon
template which lives in themytemplate.pt
file within thetemplates
directory of thetutorial
package. And indeed if you look in thetemplates
directory of this package, you'll see amytemplate.pt
template file, which renders the default home page of the generated project. This asset specification is relative (to the view.py's current package). We could have alternately an used the absolute asset specificationtutorial:templates/mytemplate.pt
, but chose to use the relative version.Since this call to
@view_config
doesn't pass aname
argument, themy_view
function which it decorates represents the "default" view callable used when the context is of the typeMyModel
.Lines 6-7. We define a
view callable
namedmy_view
, which we decorated in the step above. This view callable is a function we write generated by thezodb
scaffold that is given arequest
and which returns a dictionary. Themytemplate.pt
renderer
named by the asset specification in the step above will convert this dictionary to aresponse
on our behalf.The function returns the dictionary
{'project':'tutorial'}
. This dictionary is used by the template named by themytemplate.pt
asset specification to fill in certain values on the page.
The development.ini
(in the tutorial project
directory, as opposed to the tutorial package
directory) looks like this:
src/basiclayout/development.ini
Note the existence of an [app:main]
section which specifies our WSGI application. Our ZODB database settings are specified as the zodbconn.uri
setting within this section. This value, and the other values within this section are passed as **settings
to the main
function we defined in __init__.py
when the server is started via pserve
.