summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorChris McDonough <chrism@agendaless.com>2009-11-28 01:54:50 +0000
committerChris McDonough <chrism@agendaless.com>2009-11-28 01:54:50 +0000
commit6103bf8050466329aba930df000f042dbdff8efa (patch)
tree1dd16982214ff634d7c46082eb86468bf24a73b9 /docs
parent0970432b72d8f4360b69dc58223ea0725d747d36 (diff)
downloadpyramid-6103bf8050466329aba930df000f042dbdff8efa.tar.gz
pyramid-6103bf8050466329aba930df000f042dbdff8efa.tar.bz2
pyramid-6103bf8050466329aba930df000f042dbdff8efa.zip
Document the request-only calling convention as the default.
Diffstat (limited to 'docs')
-rw-r--r--docs/narr/MyProject/myproject/tests.py3
-rw-r--r--docs/narr/MyProject/myproject/views.py2
-rw-r--r--docs/narr/hooks.rst4
-rw-r--r--docs/narr/security.rst2
-rw-r--r--docs/narr/templates.rst14
-rw-r--r--docs/narr/unittesting.rst18
-rw-r--r--docs/narr/views.rst165
7 files changed, 101 insertions, 107 deletions
diff --git a/docs/narr/MyProject/myproject/tests.py b/docs/narr/MyProject/myproject/tests.py
index 8b3fcc73b..7c3caac74 100644
--- a/docs/narr/MyProject/myproject/tests.py
+++ b/docs/narr/MyProject/myproject/tests.py
@@ -11,8 +11,7 @@ class ViewTests(unittest.TestCase):
def test_my_view(self):
from myproject.views import my_view
- context = testing.DummyModel()
request = testing.DummyRequest()
- info = my_view(context, request)
+ info = my_view(request)
self.assertEqual(info['project'], 'MyProject')
diff --git a/docs/narr/MyProject/myproject/views.py b/docs/narr/MyProject/myproject/views.py
index 036b140fb..c43b34460 100644
--- a/docs/narr/MyProject/myproject/views.py
+++ b/docs/narr/MyProject/myproject/views.py
@@ -1,2 +1,2 @@
-def my_view(context, request):
+def my_view(request):
return {'project':'MyProject'}
diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst
index 8f6e0f62f..28a76c018 100644
--- a/docs/narr/hooks.rst
+++ b/docs/narr/hooks.rst
@@ -95,7 +95,7 @@ Here's some sample code that implements a minimal NotFound view:
from webob.exc import HTTPNotFound
- def notfound_view(context, request):
+ def notfound_view(request):
return HTTPNotFound()
.. note:: When a NotFound view is invoked, it is passed a request.
@@ -203,7 +203,7 @@ Here's some sample code that implements a minimal forbidden view:
from repoze.bfg.chameleon_zpt import render_template_to_response
- def forbidden_view(context, request):
+ def forbidden_view(request):
return render_template_to_response('templates/login_form.pt')
.. note:: When an forbidden view is invoked, it is passed
diff --git a/docs/narr/security.rst b/docs/narr/security.rst
index acc1dff01..a733aef9b 100644
--- a/docs/narr/security.rst
+++ b/docs/narr/security.rst
@@ -92,7 +92,7 @@ module of your project's package
from models import Blog
@bfg_view(for_=Blog, name='add_entry.html', permission='add')
- def blog_entry_add_view(context, request):
+ def blog_entry_add_view(request):
""" Add blog entry code goes here """
pass
diff --git a/docs/narr/templates.rst b/docs/narr/templates.rst
index e7c20795e..a94c493a6 100644
--- a/docs/narr/templates.rst
+++ b/docs/narr/templates.rst
@@ -35,7 +35,7 @@ the template from a view like so:
:linenos:
from repoze.bfg.chameleon_zpt import render_template_to_response
- def sample_view(context, request):
+ def sample_view(request):
return render_template_to_response('templates/foo.pt', foo=1, bar=2)
The first argument to ``render_template_to_response`` shown above (and
@@ -68,7 +68,7 @@ string manually as a response body. Here's an example of using
from repoze.bfg.chameleon_zpt import render_template
from webob import Response
- def sample_view(context, request):
+ def sample_view(request):
result = render_template('templates/foo.pt', foo=1, bar=2)
response = Response(result)
response.content_type = 'text/plain'
@@ -81,7 +81,7 @@ changing the content-type and status:
:linenos:
from repoze.bfg.chameleon_zpt import render_template_to_response
- def sample_view(context, request):
+ def sample_view(request):
response = render_template_to_response('templates/foo.pt', foo=1, bar=2)
response.content_type = 'text/plain'
response.status_int = 204
@@ -144,7 +144,7 @@ it in to the template being rendered. For example:
from repoze.bfg.chameleon_zpt import render_template_to_response
from repoze.bfg.chameleon_zpt import get_template
- def my_view(context, request):
+ def my_view(request):
main = get_template('templates/master.pt')
return render_template_to_response('templates/mytemplate.pt', main=main)
@@ -200,7 +200,7 @@ which renders this template:
from repoze.bfg.chameleon_text import render_template_to_response
- def text_view(context, request):
+ def text_view(request):
return render_template_to_response('templates/text.txt', name='World')
The Chameleon text rendering API is a wholesale mirror of the
@@ -291,9 +291,9 @@ installed, here's an example of using Mako from within a
from mako.template import Template
from webob import Response
- def make_view(context, request):
+ def make_view(request):
template = Template(filename='/templates/template.mak')
- result = template.render(name=context.name)
+ result = template.render(name=request.params['name'])
response = Response(result)
return response
diff --git a/docs/narr/unittesting.rst b/docs/narr/unittesting.rst
index d31be3056..d94c94d99 100644
--- a/docs/narr/unittesting.rst
+++ b/docs/narr/unittesting.rst
@@ -49,7 +49,7 @@ to unit test a :mod:`repoze.bfg` view function.
.. code-block:: python
:linenos:
- def view_fn(context, request):
+ def view_fn(request):
from repoze.bfg.chameleon_zpt import render_template_to_response
if 'say' in request.params:
return render_template_to_response('templates/submitted.pt',
@@ -88,18 +88,16 @@ unittest TestCase that used the testing API.
def test_view_fn_not_submitted(self):
from my.package import view_fn
renderer = testing.registerTemplateRenderer('templates/show.pt')
- context = testing.DummyModel()
request = testing.DummyRequest()
- response = view_fn(context, request)
+ response = view_fn(request)
renderer.assert_(say='Hello')
def test_view_fn_submitted(self):
from my.package import view_fn
renderer = testing.registerTemplateRenderer('templates/submitted.pt')
- context = testing.DummyModel()
request = testing.DummyRequest()
request.params['say'] = 'Yo'
- response = view_fn(context, request)
+ response = view_fn(request)
renderer.assert_(say='Yo')
In the above example, we create a ``MyTest`` test case that inherits
@@ -113,10 +111,9 @@ request.params) have been submitted. Its first line registers a
"dummy template renderer" named ``templates/show.pt`` via the
``registerTemplateRenderer`` function (a ``repoze.bfg.testing`` API);
this function returns a DummyTemplateRenderer instance which we hang
-on to for later. We then create a ``DummyRequest`` object (it
-simulates a WebOb request object), and we create a ``DummyModel``
-context object. We call the function being tested with the
-manufactured context and request. When the function is called,
+on to for later. We then create a ``DummyRequest`` object which
+simulates a WebOb request object). We call the function being tested
+with the manufactured request. When the function is called,
``render_template_to_response`` will call the "dummy" template
renderer object instead of the real template renderer object. When
the dummy renderer is called, it will set attributes on itself
@@ -199,9 +196,8 @@ environment.
def test_my_view(self):
from myapp.views import my_view
- context = testing.DummyModel()
request = testing.DummyRequest()
- result = my_view(context, request)
+ result = my_view(request)
self.assertEqual(result.status, '200 OK')
body = result.app_iter[0]
self.failUnless('Welcome to' in body)
diff --git a/docs/narr/views.rst b/docs/narr/views.rst
index 390be4c99..c7c0a640e 100644
--- a/docs/narr/views.rst
+++ b/docs/narr/views.rst
@@ -6,29 +6,34 @@ Views
A :term:`view callable` is a callable which is invoked when a request
enters your application. The primary job of any :mod:`repoze.bfg`
application is is to find and call a :term:`view callable` when a
-:term:`request` reaches it. A :term:`view callable` is referred to,
-in shorthand, as a :term:`view`.
+:term:`request` reaches it. A :term:`view callable` is referred to in
+shorthand as a :term:`view`.
-See :ref:`traversal_intro` for an example of how a view might be found
-as the result of a request.
+.. note:: See :ref:`traversal_intro` for an example of how a view
+ might be found as the result of a request.
-A view callable may always return a :term:`WebOb` ``Response`` object
-directly. It may optionally return another arbitrary non-`Response`
-value. If a view callable returns a non-Response result, the result
-will be converted into a response by the :term:`renderer` associated
-with the :term:`view configuration` for the view.
+Most views accept a single argument: ``request``. This argument
+represents a WebOb Request object representing the current WSGI
+request.
+
+A view callable may always return a :term:`WebOb` :term:`Response`
+object directly. It may optionally return another arbitrary
+non-Response value. If a view callable returns a non-Response result,
+the result will be converted into a response by the :term:`renderer`
+associated with the :term:`view configuration` for the view.
A view is mapped to one or more URLs by virtue of :term:`view
configuration`. View configuration is performed by using the
-``add_view`` method of a :term:`Configurator` object, by adding
-``<view>`` statements to :term:`ZCML` used by your application, or by
-attaching ``@bfg_view`` decorators to Python objects in your
-application source code. Each of these mechanisms are equivalent.
+``add_view`` method of a :term:`Configurator` object, by adding a
+``<view>`` statement to :term:`ZCML` used by your application, or by
+running a :term:`scan` against application source code which has a
+``@bfg_view`` decorator attached to a Python object. Each of these
+mechanisms are equivalent.
A view might also be mapped to a URL by virtue of :term:`route
configuration`. Route configuration is performed by using the
-``add_route`` method of a :term:`Configurator` object or by adding
-``<route>`` statements to :term:`ZCML` used by your application. See
+``add_route`` method of a :term:`Configurator` object or by adding a
+``<route>`` statement to :term:`ZCML` used by your application. See
:ref:`urldispatch_chapter` for more information on mapping URLs to
views using routes.
@@ -38,16 +43,16 @@ Defining a View as a Function
-----------------------------
The easiest way to define a view is to create a function that accepts
-two arguments: :term:`context`, and :term:`request` and which returns
-a response object. For example, this is a "hello world" view
-implemented as a function:
+a single argument: :term:`request` and which returns a response
+object. For example, this is a "hello world" view implemented as a
+function:
.. code-block:: python
:linenos:
from webob import Response
- def hello_world(context, request):
+ def hello_world(request):
return Response('Hello world!')
.. _class_as_view:
@@ -60,13 +65,13 @@ Defining a View as a Class
A view callable may also be a class instead of a function. When a
view callable is a class, the calling semantics are slightly different
than when it is a function or another non-class callable. When a view
-is a class, the class' ``__init__`` is called with the context and the
-request parameters. As a result, an instance of the class is created.
+is a class, the class' ``__init__`` is called with the request
+parameter. As a result, an instance of the class is created.
Subsequently, that instance's ``__call__`` method is invoked with no
parameters. Views defined as classes must have the following traits:
-- an ``__init__`` method that accepts a ``context`` and a ``request``
- as positional arguments.
+- an ``__init__`` method that accepts a ``request`` as its sole
+ positional arguments.
- a ``__call__`` method that accepts no parameters and returns a
response.
@@ -79,15 +84,14 @@ For example:
from webob import Response
class MyView(object):
- def __init__(self, context, request):
- self.context = context
+ def __init__(self, request):
self.request = request
def __call__(self):
- return Response('hello from %r!' % self.context)
+ return Response('hello')
-The context and request objects passed to ``__init__`` are the same
-types of objects as described in :ref:`function_as_view`.
+The request object passed to ``__init__`` is the same type of request
+object described in :ref:`function_as_view`.
If you'd like to use a different attribute than ``__call__`` to
represent the method expected to return a response, you can use an
@@ -96,61 +100,60 @@ represent the method expected to return a response, you can use an
.. _request_only_view_definitions:
-Request-Only View Definitions
------------------------------
+Request-And-Context View Definitions
+------------------------------------
View callables may alternately be defined as classes or functions (or
-any callable) that accept only a *request* object, instead of both a
-context and a request. The following types work as views in this
-style:
+any callable) that accept two positional arguments: a :term:`context`
+as the first argument and a :term:`request` as the second argument.
+The :term:`context` and :term:`request` arguments passed to a view
+function defined in this style can be defined as follows:
+
+context
+
+ An instance of a :term:`context` found via graph :term:`traversal`
+ or :term:`URL dispatch`. If the context is found via traversal, it
+ will be a :term:`model` object.
+
+request
+
+ A WebOb Request object representing the current WSGI request.
+
+The following types work as views in this style:
-#. Functions that accept a single argument ``request``, e.g.::
+#. Functions that accept two arguments: ``context``, and ``request``,
+ e.g.::
from webob import Response
- def view(request):
+ def view(context, request):
return Response('OK')
#. New-style and old-style classes that have an ``__init__`` method
- that accepts ``self, request``, e.g.::
+ that accepts ``self, context, request``, e.g.::
from webob import Response
class view(object):
- __init__(self, request):
+ __init__(self, context, request):
return Response('OK')
#. Arbitrary callables that have a ``__call__`` method that accepts
- ``self, request``, e.g.::
+ ``self, context, request``, e.g.::
from webob import Response
class View(object):
- def __call__(self, request):
+ def __call__(self, context, request):
return Response('OK')
view = View() # this is the view callable
-This style of calling convention is useful for :term:`url dispatch`
-based applications, where the context is seldom used within the view
-code itself. The view always has access to the context via
-``request.context`` in any case, so it's still available even if you
-use the request-only calling convention.
+This style of calling convention is useful for :term:`traversal` based
+applications, where the context object is frequently used within the
+view code itself.
-Arguments Passed to a View
---------------------------
-
-The :term:`context` and :term:`request` arguments passed to a view
-function can be defined as follows:
-
-context
-
- An instance of a :term:`context` found via graph :term:`traversal`
- or :term:`URL dispatch`. If the context is found via traversal, it
- will be a :term:`model` object.
-
-request
-
- A WebOb Request object representing the current WSGI request.
+No matter which view calling convention is used, the view always has
+access to the context via ``request.context``.
.. _the_response:
@@ -296,8 +299,8 @@ You can also declare a *default view* for a model type:
/>
A *default view* has no ``name`` attribute. When a :term:`context` is
-traversed and there is no *view name* in the request, the *default
-view* is the view that is used.
+found and there is no *view name* associated with the result of
+:term:`traversal`, the *default view* is the view that is used.
You can also declare that a view is good for any model type by using
the special ``*`` character in the ``for`` attribute:
@@ -629,7 +632,7 @@ An example might reside in a bfg application module ``views.py``:
@bfg_view(name='my_view', request_type='POST', for_=MyModel,
permission='read')
- def my_view(context, request):
+ def my_view(request):
return render_template_to_response('templates/my.pt')
Using this decorator as above replaces the need to add this ZCML to
@@ -720,7 +723,7 @@ All arguments may be omitted. For example:
from webob import Response
@bfg_view()
- def my_view(context, request):
+ def my_view(request):
""" My view """
return Response()
@@ -743,12 +746,11 @@ applied against a function. For example:
@bfg_view()
class MyView(object):
- def __init__(self, context, request):
- self.context = context
+ def __init__(self, request):
self.request = request
def __call__(self):
- return Response('hello from %s!' % self.context)
+ return Response('hello')
You can use the ``bfg_view`` decorator as a simple callable to
manually decorate classes in Python 2.5 and below (without the
@@ -761,12 +763,11 @@ decorator syntactic sugar), if you wish:
from repoze.bfg.view import bfg_view
class MyView(object):
- def __init__(self, context, request):
- self.context = context
+ def __init__(self, request):
self.request = request
def __call__(self):
- return Response('hello from %s!' % self.context)
+ return Response('hello')
my_view = bfg_view()(MyView)
@@ -781,7 +782,7 @@ registration. For example:
@bfg_view(name='edit')
@bfg_view(name='change')
- def edit(context, request):
+ def edit(request):
pass
This registers the same view under two different names.
@@ -800,13 +801,12 @@ The bfg_view decorator can also be used against class methods:
from repoze.bfg.view import bfg_view
class MyView(object):
- def __init__(self, context, request):
- self.context = context
+ def __init__(self, request):
self.request = request
@bfg_view(name='hello')
def amethod(self):
- return Response('hello from %s!' % self.context)
+ return Response('hello')
When the bfg_view decorator is used against a class method, a view is
registered for the *class*, so the class constructor must accept
@@ -825,12 +825,11 @@ could be spelled equivalently as the below:
@bfg_view(attr='amethod', name='hello')
class MyView(object):
- def __init__(self, context, request):
- self.context = context
+ def __init__(self, request):
self.request = request
def amethod(self):
- return Response('hello from %s!' % self.context)
+ return Response('hello')
.. note:: The ability to use the ``bfg_view`` decorator as a method
decorator is new in :mod:`repoze.bfg` version 1.1.
@@ -1019,7 +1018,7 @@ representation of the dictionary:
from repoze.bfg.view import bfg_view
@bfg_view(renderer='string')
- def hello_world(context, request):
+ def hello_world(request):
return {'content':'Hello!'}
The body of the response returned by such a view will be a string
@@ -1050,7 +1049,7 @@ view will render the returned dictionary to a JSON serialization:
from repoze.bfg.view import bfg_view
@bfg_view(renderer='json')
- def hello_world(context, request):
+ def hello_world(request):
return {'content':'Hello!'}
The body of the response returned by such a view will be a string
@@ -1208,7 +1207,7 @@ slightly different response.
from webob.exc import HTTPFound
- def myview(context, request):
+ def myview(request):
return HTTPFound(location='http://example.com')
All exception types from the :mod:`webob.exc` module implement the
@@ -1344,7 +1343,7 @@ ZCML file:
from repoze.bfg.url import static_url
from repoze.bfg.chameleon_zpt import render_template_to_response
- def my_view(context, request):
+ def my_view(request):
css_url = static_url('resources/1/foo.css', request)
js_url = static_url('resources/2/foo.js', request)
return render_template_to_response('templates/my_template.pt',
@@ -1484,7 +1483,7 @@ accept a form post from the above form:
.. code-block:: python
- def myview(context, request):
+ def myview(request):
firstname = request.params['firstname']
lastname = request.params['lastname']
@@ -1494,7 +1493,7 @@ decode already-decoded (``unicode``) values obtained from
.. code-block:: python
- def myview(context, request):
+ def myview(request):
# the .decode('utf-8') will break below if there are any high-order
# characters in the firstname or lastname
firstname = request.params['firstname'].decode('utf-8')
@@ -1695,7 +1694,7 @@ attribute:
from repoze.bfg.view import bfg_view
@bfg_view(renderer='amf')
- def myview(context, request):
+ def myview(request):
return {'Hello':'world'}
By default, when a template extension is unrecognized, an error is