diff options
Diffstat (limited to 'docs/narr/models.rst')
| -rw-r--r-- | docs/narr/models.rst | 103 |
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) |
