summaryrefslogtreecommitdiff
path: root/docs/narr/models.rst
diff options
context:
space:
mode:
Diffstat (limited to 'docs/narr/models.rst')
-rw-r--r--docs/narr/models.rst103
1 files changed, 56 insertions, 47 deletions
diff --git a/docs/narr/models.rst b/docs/narr/models.rst
index 2c72e766d..79286590a 100644
--- a/docs/narr/models.rst
+++ b/docs/narr/models.rst
@@ -5,8 +5,8 @@ A :term:`model` class is typically a simple Python class defined in a
module. References to these classes and instances of such classes are
omnipresent in :app:`Pyramid`:
-- Model instances make up the graph that :app:`Pyramid` is
- willing to walk over when :term:`traversal` is used.
+- Model instances make up the object graph that :app:`Pyramid`
+ will walk over when :term:`traversal` is used.
- The ``context`` and ``containment`` arguments to
:meth:`pyramid.config.Configurator.add_view` often
@@ -72,7 +72,7 @@ instance.
A model constructor may be essentially any Python object which is
callable, and which returns a model instance. In the above example,
-the ``BlogEntry`` class can be "called", returning a model instance.
+the ``BlogEntry`` class can be called, returning a model instance.
.. index::
single: model interfaces
@@ -130,8 +130,9 @@ that a model implements an interface by using the
``BlogEntry`` model implements the ``IBlogEntry`` interface.
You can also specify that a *particular* model instance provides an
-interface (as opposed to its class). To do so, use the
-:func:`zope.interface.directlyProvides` function:
+interface, as opposed to its class as above, which implies that all
+instances do. To do so, use the :func:`zope.interface.directlyProvides`
+function:
.. code-block:: python
:linenos:
@@ -202,18 +203,18 @@ Defining a Graph of Model Instances for Traversal
When :term:`traversal` is used (as opposed to a purely :term:`url
dispatch` based application), :app:`Pyramid` expects to be able to
traverse a graph composed of model instances. Traversal begins at a
-root model, and descends into the graph recursively via each found
-model's ``__getitem__`` method. :app:`Pyramid` imposes the
+root model instance, and descends into the graph recursively via each
+found model's ``__getitem__`` method. :app:`Pyramid` imposes the
following policy on model instance nodes in the graph:
-- Nodes which contain other nodes (aka "container" nodes) must supply
+- Container nodes (i.e., nodes which contain other nodes) must supply
a ``__getitem__`` method which is willing to resolve a unicode name
to a subobject. If a subobject by that name does not exist in the
container, ``__getitem__`` must raise a :exc:`KeyError`. If a
subobject by that name *does* exist, the container should return the
subobject (another model instance).
-- Nodes which do not contain other nodes (aka "leaf" nodes) must not
+- Leaf nodes, which do not contain other nodes, must not
implement a ``__getitem__``, or if they do, their ``__getitem__``
method must raise a :exc:`KeyError`.
@@ -228,40 +229,17 @@ works against model instances.
Location-Aware Model Instances
------------------------------
-.. sidebar:: Using :mod:`repoze.bfg.traversalwrapper`
-
- If you'd rather not manage the ``__name__`` and ``__parent__``
- attributes of your models "by hand", an add on package named
- :mod:`repoze.bfg.traversalwrapper` can help.
-
- In order to use this helper feature, you must first install the
- :mod:`repoze.bfg.traversalwrapper` package (available via `SVN
- <http://svn.repoze.org/repoze.bfg.traversalwrapper>`_), then
- register its ``ModelGraphTraverser`` as the traversal policy, rather
- than the default :app:`Pyramid` traverser. The package contains
- instructions.
-
- Once :app:`Pyramid` is configured with this feature, you will no
- longer need to manage the ``__parent__`` and ``__name__`` attributes
- on graph objects "by hand". Instead, as necessary, during traversal
- :app:`Pyramid` will wrap each object (even the root object) in a
- ``LocationProxy`` which will dynamically assign a ``__name__`` and a
- ``__parent__`` to the traversed object (based on the last traversed
- object and the name supplied to ``__getitem__``). The root object
- will have a ``__name__`` attribute of ``None`` and a ``__parent__``
- attribute of ``None``.
-
Applications which use :term:`traversal` to locate the :term:`context`
of a view must ensure that the model instances that make up the model
graph are "location aware".
In order for :app:`Pyramid` location, security, URL-generation, and
-traversal functions (such as the functions exposed in
-:ref:`location_module`, :ref:`traversal_module`, and :ref:`url_module`
-as well as certain functions in :ref:`security_module` ) to work
-properly against the instances in an object graph, all nodes in the
-graph must be :term:`location` -aware. This means they must have two
-attributes: ``__parent__`` and ``__name__``.
+traversal functions (i.e., functions in :ref:`location_module`,
+:ref:`traversal_module`, :ref:`url_module` and some in
+:ref:`security_module` ) to work properly against the model instances in
+an object graph, all nodes in the graph must be :term:`location` -aware.
+This means they must have two attributes: ``__parent__`` and
+``__name__``.
The ``__parent__`` attribute should be a reference to the node's
parent model instance in the graph. The ``__name__`` attribute should
@@ -278,15 +256,23 @@ The ``__parent__`` of the root object should be ``None`` and its
__name__ = ''
__parent__ = None
-A node returned from the root item's ``__getitem__`` method should
-have a ``__parent__`` attribute that is a reference to the root
-object, and its ``__name__`` attribute should match the name by which
-it is reachable via the root object's ``__getitem__``. *That*
-object's ``__getitem__`` should return objects that have a
-``__parent__`` attribute that points at that object, and
-``__getitem__``-returned objects should have a ``__name__`` attribute
-that matches the name by which they are retrieved via ``__getitem__``,
-and so on.
+A node returned from the root item's ``__getitem__`` method should have
+a ``__parent__`` attribute that is a reference to the root object, and
+its ``__name__`` attribute should match the name by which it is
+reachable via the root object's ``__getitem__``. A container under the
+root should have a ``__getitem__`` that returns objects with a
+``__parent__`` attribute that points at the container, and these
+subobjects should have a ``__name__`` attribute that matches the name by
+which they are retrieved from the container via ``__getitem__``.
+This pattern continues recursively down the graph.
+
+The ``__parent__`` attributes of each node form a linked list
+that points "upward" toward the root. This is analogous to the
+`..` entry in filesystem directories. If you follow the ``__parent__``
+values from any node in the traversal graph, you will eventually
+come to the root node, just like if you keep executing the
+``cd ..`` filesystem command, eventually you will reach the
+filesystem root directory.
.. warning:: If your root model object has a ``__name__`` argument
that is not ``None`` or the empty string, URLs returned by the
@@ -297,6 +283,29 @@ and so on.
to every path and URL generated (as opposed to a single leading
slash or empty tuple element).
+.. sidebar:: Using :mod:`repoze.bfg.traversalwrapper`
+
+ If you'd rather not manage the ``__name__`` and ``__parent__``
+ attributes of your models "by hand", an add-on package named
+ :mod:`repoze.bfg.traversalwrapper` can help.
+
+ In order to use this helper feature, you must first install the
+ :mod:`repoze.bfg.traversalwrapper` package (available via `SVN
+ <http://svn.repoze.org/repoze.bfg.traversalwrapper>`_), then
+ register its ``ModelGraphTraverser`` as the traversal policy, rather
+ than the default :app:`Pyramid` traverser. The package contains
+ instructions for doing so.
+
+ Once :app:`Pyramid` is configured with this feature, you will no
+ longer need to manage the ``__parent__`` and ``__name__`` attributes
+ on graph objects "by hand". Instead, as necessary, during traversal
+ :app:`Pyramid` will wrap each object (even the root object) in a
+ ``LocationProxy`` which will dynamically assign a ``__name__`` and a
+ ``__parent__`` to the traversed object (based on the last traversed
+ object and the name supplied to ``__getitem__``). The root object
+ will have a ``__name__`` attribute of ``None`` and a ``__parent__``
+ attribute of ``None``.
+
.. index::
single: model API functions
single: url generation (traversal)