commit | author | age
|
8a1b50
|
1 |
.. _view_config_chapter: |
CD |
2 |
|
|
3 |
.. _view_configuration: |
|
4 |
|
e81ad8
|
5 |
.. _view_lookup: |
CM |
6 |
|
8a1b50
|
7 |
View Configuration |
CD |
8 |
================== |
|
9 |
|
|
10 |
.. index:: |
|
11 |
single: view lookup |
|
12 |
|
|
13 |
:term:`View lookup` is the :app:`Pyramid` subsystem responsible for finding |
e81ad8
|
14 |
an invoking a :term:`view callable`. :term:`View configuration` controls how |
CM |
15 |
:term:`view lookup` operates in your application. During any given request, |
|
16 |
view configuration information is compared against request data by the view |
|
17 |
lookup subsystem in order to find the "best" view callable for that request. |
8a1b50
|
18 |
|
e81ad8
|
19 |
In earlier chapters, you have been exposed to a few simple view configuration |
CM |
20 |
declarations without much explanation. In this chapter we will explore the |
|
21 |
subject in detail. |
8a1b50
|
22 |
|
CD |
23 |
Mapping a Resource or URL Pattern to a View Callable |
|
24 |
---------------------------------------------------- |
|
25 |
|
|
26 |
A developer makes a :term:`view callable` available for use within a |
|
27 |
:app:`Pyramid` application via :term:`view configuration`. A view |
|
28 |
configuration associates a view callable with a set of statements that |
|
29 |
determine the set of circumstances which must be true for the view callable |
|
30 |
to be invoked. |
|
31 |
|
|
32 |
A view configuration statement is made about information present in the |
|
33 |
:term:`context` resource and the :term:`request`. |
|
34 |
|
026da8
|
35 |
View configuration is performed in one of two ways: |
8a1b50
|
36 |
|
CD |
37 |
- by running a :term:`scan` against application source code which has a |
|
38 |
:class:`pyramid.view.view_config` decorator attached to a Python object as |
70acd2
|
39 |
per :ref:`mapping_views_using_a_decorator_section`. |
8a1b50
|
40 |
|
CD |
41 |
- by using the :meth:`pyramid.config.Configurator.add_view` method as per |
|
42 |
:ref:`mapping_views_using_imperative_config_section`. |
|
43 |
|
|
44 |
.. _view_configuration_parameters: |
|
45 |
|
|
46 |
View Configuration Parameters |
|
47 |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
48 |
|
|
49 |
All forms of view configuration accept the same general types of arguments. |
|
50 |
|
|
51 |
Many arguments supplied during view configuration are :term:`view predicate` |
|
52 |
arguments. View predicate arguments used during view configuration are used |
db14e3
|
53 |
to narrow the set of circumstances in which :term:`view lookup` will find a |
2e3f70
|
54 |
particular view callable. |
8a1b50
|
55 |
|
e81ad8
|
56 |
:term:`View predicate` attributes are an important part of view configuration |
CM |
57 |
that enables the :term:`view lookup` subsystem to find and invoke the |
|
58 |
appropriate view. The greater number of predicate attributes possessed by a |
|
59 |
view's configuration, the more specific the circumstances need to be before |
|
60 |
the registered view callable will be invoked. The fewer number of predicates |
|
61 |
which are supplied to a particular view configuration, the more likely it is |
|
62 |
that the associated view callable will be invoked. A view with five |
|
63 |
predicates will always be found and evaluated before a view with two, for |
|
64 |
example. All predicates must match for the associated view to be called. |
8a1b50
|
65 |
|
CD |
66 |
This does not mean however, that :app:`Pyramid` "stops looking" when it |
|
67 |
finds a view registration with predicates that don't match. If one set |
|
68 |
of view predicates does not match, the "next most specific" view (if |
|
69 |
any) is consulted for predicates, and so on, until a view is found, or |
|
70 |
no view can be matched up with the request. The first view with a set |
|
71 |
of predicates all of which match the request environment will be |
|
72 |
invoked. |
|
73 |
|
|
74 |
If no view can be found with predicates which allow it to be matched up with |
|
75 |
the request, :app:`Pyramid` will return an error to the user's browser, |
|
76 |
representing a "not found" (404) page. See :ref:`changing_the_notfound_view` |
|
77 |
for more information about changing the default notfound view. |
|
78 |
|
e81ad8
|
79 |
Other view configuration arguments are non-predicate arguments. These tend |
CM |
80 |
to modify the response of the view callable or prevent the view callable from |
8a1b50
|
81 |
being invoked due to an authorization policy. The presence of non-predicate |
CD |
82 |
arguments in a view configuration does not narrow the circumstances in which |
|
83 |
the view callable will be invoked. |
|
84 |
|
e573d4
|
85 |
.. _nonpredicate_view_args: |
CM |
86 |
|
8a1b50
|
87 |
Non-Predicate Arguments |
CD |
88 |
+++++++++++++++++++++++ |
|
89 |
|
|
90 |
``permission`` |
|
91 |
The name of a :term:`permission` that the user must possess in order to |
|
92 |
invoke the :term:`view callable`. See :ref:`view_security_section` for |
|
93 |
more information about view security and permissions. |
2e3f70
|
94 |
|
8a1b50
|
95 |
If ``permission`` is not supplied, no permission is registered for this |
CD |
96 |
view (it's accessible by any caller). |
|
97 |
|
|
98 |
``attr`` |
|
99 |
The view machinery defaults to using the ``__call__`` method of the |
|
100 |
:term:`view callable` (or the function itself, if the view callable is a |
|
101 |
function) to obtain a response. The ``attr`` value allows you to vary the |
|
102 |
method attribute used to obtain the response. For example, if your view |
|
103 |
was a class, and the class has a method named ``index`` and you wanted to |
|
104 |
use this method instead of the class' ``__call__`` method to return the |
|
105 |
response, you'd say ``attr="index"`` in the view configuration for the |
|
106 |
view. This is most useful when the view definition is a class. |
|
107 |
|
|
108 |
If ``attr`` is not supplied, ``None`` is used (implying the function itself |
|
109 |
if the view is a function, or the ``__call__`` callable attribute if the |
|
110 |
view is a class). |
|
111 |
|
|
112 |
``renderer`` |
|
113 |
Denotes the :term:`renderer` implementation which will be used to construct |
|
114 |
a :term:`response` from the associated view callable's return value. (see |
|
115 |
also :ref:`renderers_chapter`). |
|
116 |
|
|
117 |
This is either a single string term (e.g. ``json``) or a string implying a |
|
118 |
path or :term:`asset specification` (e.g. ``templates/views.pt``) naming a |
|
119 |
:term:`renderer` implementation. If the ``renderer`` value does not |
|
120 |
contain a dot (``.``), the specified string will be used to look up a |
|
121 |
renderer implementation, and that renderer implementation will be used to |
|
122 |
construct a response from the view return value. If the ``renderer`` value |
|
123 |
contains a dot (``.``), the specified term will be treated as a path, and |
|
124 |
the filename extension of the last element in the path will be used to look |
|
125 |
up the renderer implementation, which will be passed the full path. |
|
126 |
|
|
127 |
When the renderer is a path, although a path is usually just a simple |
|
128 |
relative pathname (e.g. ``templates/foo.pt``, implying that a template |
|
129 |
named "foo.pt" is in the "templates" directory relative to the directory of |
|
130 |
the current :term:`package`), a path can be absolute, starting with a slash |
|
131 |
on UNIX or a drive letter prefix on Windows. The path can alternately be a |
|
132 |
:term:`asset specification` in the form |
|
133 |
``some.dotted.package_name:relative/path``, making it possible to address |
|
134 |
template assets which live in a separate package. |
|
135 |
|
|
136 |
The ``renderer`` attribute is optional. If it is not defined, the "null" |
|
137 |
renderer is assumed (no rendering is performed and the value is passed back |
7a2ab7
|
138 |
to the upstream :app:`Pyramid` machinery unchanged). Note that if the |
8a1b50
|
139 |
view callable itself returns a :term:`response` (see :ref:`the_response`), |
CD |
140 |
the specified renderer implementation is never called. |
|
141 |
|
0fa199
|
142 |
``http_cache`` |
CM |
143 |
When you supply an ``http_cache`` value to a view configuration, the |
|
144 |
``Expires`` and ``Cache-Control`` headers of a response generated by the |
|
145 |
associated view callable are modified. The value for ``http_cache`` may be |
|
146 |
one of the following: |
|
147 |
|
|
148 |
- A nonzero integer. If it's a nonzero integer, it's treated as a number |
|
149 |
of seconds. This number of seconds will be used to compute the |
|
150 |
``Expires`` header and the ``Cache-Control: max-age`` parameter of |
|
151 |
responses to requests which call this view. For example: |
|
152 |
``http_cache=3600`` instructs the requesting browser to 'cache this |
|
153 |
response for an hour, please'. |
|
154 |
|
|
155 |
- A ``datetime.timedelta`` instance. If it's a ``datetime.timedelta`` |
|
156 |
instance, it will be converted into a number of seconds, and that number |
|
157 |
of seconds will be used to compute the ``Expires`` header and the |
|
158 |
``Cache-Control: max-age`` parameter of responses to requests which call |
|
159 |
this view. For example: ``http_cache=datetime.timedelta(days=1)`` |
|
160 |
instructs the requesting browser to 'cache this response for a day, |
|
161 |
please'. |
|
162 |
|
|
163 |
- Zero (``0``). If the value is zero, the ``Cache-Control`` and |
|
164 |
``Expires`` headers present in all responses from this view will be |
|
165 |
composed such that client browser cache (and any intermediate caches) are |
|
166 |
instructed to never cache the response. |
|
167 |
|
|
168 |
- A two-tuple. If it's a two tuple (e.g. ``http_cache=(1, |
|
169 |
{'public':True})``), the first value in the tuple may be a nonzero |
|
170 |
integer or a ``datetime.timedelta`` instance; in either case this value |
|
171 |
will be used as the number of seconds to cache the response. The second |
|
172 |
value in the tuple must be a dictionary. The values present in the |
|
173 |
dictionary will be used as input to the ``Cache-Control`` response |
|
174 |
header. For example: ``http_cache=(3600, {'public':True})`` means 'cache |
|
175 |
for an hour, and add ``public`` to the Cache-Control header of the |
|
176 |
response'. All keys and values supported by the |
|
177 |
``webob.cachecontrol.CacheControl`` interface may be added to the |
|
178 |
dictionary. Supplying ``{'public':True}`` is equivalent to calling |
|
179 |
``response.cache_control.public = True``. |
|
180 |
|
|
181 |
Providing a non-tuple value as ``http_cache`` is equivalent to calling |
|
182 |
``response.cache_expires(value)`` within your view's body. |
|
183 |
|
|
184 |
Providing a two-tuple value as ``http_cache`` is equivalent to calling |
|
185 |
``response.cache_expires(value[0], **value[1])`` within your view's body. |
|
186 |
|
|
187 |
If you wish to avoid influencing, the ``Expires`` header, and instead wish |
|
188 |
to only influence ``Cache-Control`` headers, pass a tuple as ``http_cache`` |
|
189 |
with the first element of ``None``, e.g.: ``(None, {'public':True})``. |
|
190 |
|
8a1b50
|
191 |
``wrapper`` |
CD |
192 |
The :term:`view name` of a different :term:`view configuration` which will |
|
193 |
receive the response body of this view as the ``request.wrapped_body`` |
|
194 |
attribute of its own :term:`request`, and the :term:`response` returned by |
|
195 |
this view as the ``request.wrapped_response`` attribute of its own request. |
|
196 |
Using a wrapper makes it possible to "chain" views together to form a |
|
197 |
composite response. The response of the outermost wrapper view will be |
|
198 |
returned to the user. The wrapper view will be found as any view is found: |
|
199 |
see :ref:`view_lookup`. The "best" wrapper view will be found based on the |
|
200 |
lookup ordering: "under the hood" this wrapper view is looked up via |
|
201 |
``pyramid.view.render_view_to_response(context, request, |
|
202 |
'wrapper_viewname')``. The context and request of a wrapper view is the |
|
203 |
same context and request of the inner view. |
|
204 |
|
|
205 |
If ``wrapper`` is not supplied, no wrapper view is used. |
|
206 |
|
f7f0dd
|
207 |
``decorator`` |
86fc0c
|
208 |
A :term:`dotted Python name` to a function (or the function itself) which |
f7f0dd
|
209 |
will be used to decorate the registered :term:`view callable`. The |
CM |
210 |
decorator function will be called with the view callable as a single |
|
211 |
argument. The view callable it is passed will accept ``(context, |
|
212 |
request)``. The decorator must return a replacement view callable which |
|
213 |
also accepts ``(context, request)``. |
2e3f70
|
214 |
|
f7f0dd
|
215 |
``mapper`` |
CM |
216 |
A Python object or :term:`dotted Python name` which refers to a :term:`view |
|
217 |
mapper`, or ``None``. By default it is ``None``, which indicates that the |
|
218 |
view should use the default view mapper. This plug-point is useful for |
|
219 |
Pyramid extension developers, but it's not very useful for 'civilians' who |
|
220 |
are just developing stock Pyramid applications. Pay no attention to the man |
|
221 |
behind the curtain. |
|
222 |
|
8a1b50
|
223 |
Predicate Arguments |
CD |
224 |
+++++++++++++++++++ |
|
225 |
|
|
226 |
These arguments modify view lookup behavior. In general, the more predicate |
|
227 |
arguments that are supplied, the more specific, and narrower the usage of the |
|
228 |
configured view. |
|
229 |
|
|
230 |
``name`` |
|
231 |
The :term:`view name` required to match this view callable. Read |
|
232 |
:ref:`traversal_chapter` to understand the concept of a view name. |
|
233 |
|
|
234 |
If ``name`` is not supplied, the empty string is used (implying the default |
|
235 |
view). |
|
236 |
|
|
237 |
``context`` |
|
238 |
An object representing a Python class that the :term:`context` resource |
|
239 |
must be an instance of *or* the :term:`interface` that the :term:`context` |
|
240 |
resource must provide in order for this view to be found and called. This |
|
241 |
predicate is true when the :term:`context` resource is an instance of the |
|
242 |
represented class or if the :term:`context` resource provides the |
|
243 |
represented interface; it is otherwise false. |
|
244 |
|
|
245 |
If ``context`` is not supplied, the value ``None``, which matches any |
|
246 |
resource, is used. |
|
247 |
|
|
248 |
``route_name`` |
|
249 |
If ``route_name`` is supplied, the view callable will be invoked only when |
|
250 |
the named route has matched. |
|
251 |
|
|
252 |
This value must match the ``name`` of a :term:`route configuration` |
|
253 |
declaration (see :ref:`urldispatch_chapter`) that must match before this |
|
254 |
view will be called. Note that the ``route`` configuration referred to by |
|
255 |
``route_name`` will usually have a ``*traverse`` token in the value of its |
|
256 |
``pattern``, representing a part of the path that will be used by |
|
257 |
:term:`traversal` against the result of the route's :term:`root factory`. |
|
258 |
|
2e3f70
|
259 |
If ``route_name`` is not supplied, the view callable will only have a chance |
8a1b50
|
260 |
of being invoked if no other route was matched. This is when the |
CD |
261 |
request/context pair found via :term:`resource location` does not indicate |
|
262 |
it matched any configured route. |
|
263 |
|
|
264 |
``request_type`` |
|
265 |
This value should be an :term:`interface` that the :term:`request` must |
|
266 |
provide in order for this view to be found and called. |
|
267 |
|
|
268 |
If ``request_type`` is not supplied, the value ``None`` is used, implying |
|
269 |
any request type. |
|
270 |
|
|
271 |
*This is an advanced feature, not often used by "civilians"*. |
|
272 |
|
|
273 |
``request_method`` |
86fc0c
|
274 |
This value can be one of the strings ``GET``, ``POST``, ``PUT``, |
8a1b50
|
275 |
``DELETE``, or ``HEAD`` representing an HTTP ``REQUEST_METHOD``. A view |
CD |
276 |
declaration with this argument ensures that the view will only be called |
|
277 |
when the request's ``method`` attribute (aka the ``REQUEST_METHOD`` of the |
|
278 |
WSGI environment) string matches the supplied value. |
|
279 |
|
|
280 |
If ``request_method`` is not supplied, the view will be invoked regardless |
|
281 |
of the ``REQUEST_METHOD`` of the :term:`WSGI` environment. |
|
282 |
|
|
283 |
``request_param`` |
|
284 |
This value can be any string. A view declaration with this argument |
|
285 |
ensures that the view will only be called when the :term:`request` has a |
|
286 |
key in the ``request.params`` dictionary (an HTTP ``GET`` or ``POST`` |
|
287 |
variable) that has a name which matches the supplied value. |
|
288 |
|
|
289 |
If the value supplied has a ``=`` sign in it, |
fe164c
|
290 |
e.g. ``request_param="foo=123"``, then the key (``foo``) must both exist |
8a1b50
|
291 |
in the ``request.params`` dictionary, *and* the value must match the right |
CD |
292 |
hand side of the expression (``123``) for the view to "match" the current |
|
293 |
request. |
|
294 |
|
|
295 |
If ``request_param`` is not supplied, the view will be invoked without |
|
296 |
consideration of keys and values in the ``request.params`` dictionary. |
|
297 |
|
|
298 |
``containment`` |
|
299 |
This value should be a reference to a Python class or :term:`interface` |
|
300 |
that a parent object in the context resource's :term:`lineage` must provide |
|
301 |
in order for this view to be found and called. The resources in your |
|
302 |
resource tree must be "location-aware" to use this feature. |
|
303 |
|
|
304 |
If ``containment`` is not supplied, the interfaces and classes in the |
|
305 |
lineage are not considered when deciding whether or not to invoke the view |
|
306 |
callable. |
|
307 |
|
|
308 |
See :ref:`location_aware` for more information about location-awareness. |
|
309 |
|
|
310 |
``xhr`` |
|
311 |
This value should be either ``True`` or ``False``. If this value is |
|
312 |
specified and is ``True``, the :term:`WSGI` environment must possess an |
|
313 |
``HTTP_X_REQUESTED_WITH`` (aka ``X-Requested-With``) header that has the |
|
314 |
value ``XMLHttpRequest`` for the associated view callable to be found and |
|
315 |
called. This is useful for detecting AJAX requests issued from jQuery, |
|
316 |
Prototype and other Javascript libraries. |
|
317 |
|
|
318 |
If ``xhr`` is not specified, the ``HTTP_X_REQUESTED_WITH`` HTTP header is |
|
319 |
not taken into consideration when deciding whether or not to invoke the |
|
320 |
associated view callable. |
|
321 |
|
|
322 |
``accept`` |
|
323 |
The value of this argument represents a match query for one or more |
|
324 |
mimetypes in the ``Accept`` HTTP request header. If this value is |
|
325 |
specified, it must be in one of the following forms: a mimetype match token |
|
326 |
in the form ``text/plain``, a wildcard mimetype match token in the form |
|
327 |
``text/*`` or a match-all wildcard mimetype match token in the form |
|
328 |
``*/*``. If any of the forms matches the ``Accept`` header of the request, |
|
329 |
this predicate will be true. |
|
330 |
|
|
331 |
If ``accept`` is not specified, the ``HTTP_ACCEPT`` HTTP header is not |
|
332 |
taken into consideration when deciding whether or not to invoke the |
|
333 |
associated view callable. |
|
334 |
|
|
335 |
``header`` |
|
336 |
This value represents an HTTP header name or a header name/value pair. |
|
337 |
|
|
338 |
If ``header`` is specified, it must be a header name or a |
|
339 |
``headername:headervalue`` pair. |
|
340 |
|
|
341 |
If ``header`` is specified without a value (a bare header name only, |
|
342 |
e.g. ``If-Modified-Since``), the view will only be invoked if the HTTP |
|
343 |
header exists with any value in the request. |
|
344 |
|
|
345 |
If ``header`` is specified, and possesses a name/value pair |
|
346 |
(e.g. ``User-Agent:Mozilla/.*``), the view will only be invoked if the HTTP |
|
347 |
header exists *and* the HTTP header matches the value requested. When the |
|
348 |
``headervalue`` contains a ``:`` (colon), it will be considered a |
|
349 |
name/value pair (e.g. ``User-Agent:Mozilla/.*`` or ``Host:localhost``). |
|
350 |
The value portion should be a regular expression. |
|
351 |
|
|
352 |
Whether or not the value represents a header name or a header name/value |
|
353 |
pair, the case of the header name is not significant. |
|
354 |
|
|
355 |
If ``header`` is not specified, the composition, presence or absence of |
|
356 |
HTTP headers is not taken into consideration when deciding whether or not |
|
357 |
to invoke the associated view callable. |
|
358 |
|
|
359 |
``path_info`` |
|
360 |
This value represents a regular expression pattern that will be tested |
|
361 |
against the ``PATH_INFO`` WSGI environment variable to decide whether or |
|
362 |
not to call the associated view callable. If the regex matches, this |
|
363 |
predicate will be ``True``. |
|
364 |
|
|
365 |
If ``path_info`` is not specified, the WSGI ``PATH_INFO`` is not taken into |
|
366 |
consideration when deciding whether or not to invoke the associated view |
|
367 |
callable. |
|
368 |
|
|
369 |
``custom_predicates`` |
|
370 |
If ``custom_predicates`` is specified, it must be a sequence of references |
|
371 |
to custom predicate callables. Use custom predicates when no set of |
|
372 |
predefined predicates do what you need. Custom predicates can be combined |
|
373 |
with predefined predicates as necessary. Each custom predicate callable |
|
374 |
should accept two arguments: ``context`` and ``request`` and should return |
|
375 |
either ``True`` or ``False`` after doing arbitrary evaluation of the |
|
376 |
context resource and/or the request. If all callables return ``True``, the |
|
377 |
associated view callable will be considered viable for a given request. |
|
378 |
|
|
379 |
If ``custom_predicates`` is not specified, no custom predicates are |
|
380 |
used. |
|
381 |
|
|
382 |
.. index:: |
|
383 |
single: view_config decorator |
|
384 |
|
|
385 |
.. _mapping_views_using_a_decorator_section: |
|
386 |
|
e81ad8
|
387 |
Adding View Configuration Using the ``@view_config`` Decorator |
CM |
388 |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
8a1b50
|
389 |
|
CD |
390 |
.. warning:: |
|
391 |
|
|
392 |
Using this feature tends to slows down application startup slightly, as |
|
393 |
more work is performed at application startup to scan for view |
e81ad8
|
394 |
configuration declarations. For maximum startup performance, use the view |
CM |
395 |
configuration method described in |
|
396 |
:ref:`mapping_views_using_imperative_config_section` instead. |
8a1b50
|
397 |
|
e81ad8
|
398 |
The :class:`~pyramid.view.view_config` decorator can be used to associate |
CM |
399 |
:term:`view configuration` information with a function, method, or class that |
|
400 |
acts as a :app:`Pyramid` view callable. |
8a1b50
|
401 |
|
026da8
|
402 |
Here's an example of the :class:`~pyramid.view.view_config` decorator that |
CM |
403 |
lives within a :app:`Pyramid` application module ``views.py``: |
8a1b50
|
404 |
|
CD |
405 |
.. ignore-next-block |
|
406 |
.. code-block:: python |
|
407 |
:linenos: |
|
408 |
|
|
409 |
from resources import MyResource |
|
410 |
from pyramid.view import view_config |
|
411 |
from pyramid.response import Response |
|
412 |
|
|
413 |
@view_config(name='my_view', request_method='POST', context=MyResource, |
|
414 |
permission='read') |
|
415 |
def my_view(request): |
|
416 |
return Response('OK') |
|
417 |
|
|
418 |
Using this decorator as above replaces the need to add this imperative |
|
419 |
configuration stanza: |
|
420 |
|
|
421 |
.. ignore-next-block |
|
422 |
.. code-block:: python |
|
423 |
:linenos: |
|
424 |
|
0fa199
|
425 |
config.add_view('mypackage.views.my_view', name='my_view', |
CM |
426 |
request_method='POST', context=MyResource, |
|
427 |
permission='read') |
8a1b50
|
428 |
|
CD |
429 |
All arguments to ``view_config`` may be omitted. For example: |
|
430 |
|
|
431 |
.. code-block:: python |
|
432 |
:linenos: |
|
433 |
|
|
434 |
from pyramid.response import Response |
|
435 |
from pyramid.view import view_config |
|
436 |
|
|
437 |
@view_config() |
|
438 |
def my_view(request): |
|
439 |
""" My view """ |
|
440 |
return Response() |
|
441 |
|
|
442 |
Such a registration as the one directly above implies that the view name will |
|
443 |
be ``my_view``, registered with a ``context`` argument that matches any |
|
444 |
resource type, using no permission, registered against requests with any |
|
445 |
request method, request type, request param, route name, or containment. |
|
446 |
|
|
447 |
The mere existence of a ``@view_config`` decorator doesn't suffice to perform |
|
448 |
view configuration. All that the decorator does is "annotate" the function |
|
449 |
with your configuration declarations, it doesn't process them. To make |
|
450 |
:app:`Pyramid` process your :class:`pyramid.view.view_config` declarations, |
86fc0c
|
451 |
you *must* use the ``scan`` method of a |
8a1b50
|
452 |
:class:`pyramid.config.Configurator`: |
CD |
453 |
|
|
454 |
.. code-block:: python |
|
455 |
:linenos: |
|
456 |
|
|
457 |
# config is assumed to be an instance of the |
|
458 |
# pyramid.config.Configurator class |
|
459 |
config.scan() |
|
460 |
|
|
461 |
Please see :ref:`decorations_and_code_scanning` for detailed information |
|
462 |
about what happens when code is scanned for configuration declarations |
70acd2
|
463 |
resulting from use of decorators like :class:`~pyramid.view.view_config`. |
8a1b50
|
464 |
|
CD |
465 |
See :ref:`configuration_module` for additional API arguments to the |
70acd2
|
466 |
:meth:`~pyramid.config.Configurator.scan` method. For example, the method |
8a1b50
|
467 |
allows you to supply a ``package`` argument to better control exactly *which* |
CD |
468 |
code will be scanned. |
e81ad8
|
469 |
|
CM |
470 |
All arguments to the :class:`~pyramid.view.view_config` decorator mean |
|
471 |
precisely the same thing as they would if they were passed as arguments to |
|
472 |
the :meth:`pyramid.config.Configurator.add_view` method save for the ``view`` |
|
473 |
argument. Usage of the :class:`~pyramid.view.view_config` decorator is a |
|
474 |
form of :term:`declarative configuration`, while |
|
475 |
:meth:`pyramid.config.Configurator.add_view` is a form of :term:`imperative |
|
476 |
configuration`. However, they both do the same thing. |
8a1b50
|
477 |
|
CD |
478 |
``@view_config`` Placement |
|
479 |
++++++++++++++++++++++++++ |
|
480 |
|
70acd2
|
481 |
A :class:`~pyramid.view.view_config` decorator can be placed in various points |
8a1b50
|
482 |
in your application. |
CD |
483 |
|
|
484 |
If your view callable is a function, it may be used as a function decorator: |
|
485 |
|
|
486 |
.. code-block:: python |
|
487 |
:linenos: |
|
488 |
|
|
489 |
from pyramid.view import view_config |
|
490 |
from pyramid.response import Response |
|
491 |
|
|
492 |
@view_config(name='edit') |
|
493 |
def edit(request): |
|
494 |
return Response('edited!') |
|
495 |
|
|
496 |
If your view callable is a class, the decorator can also be used as a class |
|
497 |
decorator in Python 2.6 and better (Python 2.5 and below do not support class |
|
498 |
decorators). All the arguments to the decorator are the same when applied |
|
499 |
against a class as when they are applied against a function. For example: |
|
500 |
|
|
501 |
.. code-block:: python |
|
502 |
:linenos: |
|
503 |
|
|
504 |
from pyramid.response import Response |
|
505 |
from pyramid.view import view_config |
|
506 |
|
|
507 |
@view_config() |
|
508 |
class MyView(object): |
|
509 |
def __init__(self, request): |
|
510 |
self.request = request |
|
511 |
|
|
512 |
def __call__(self): |
|
513 |
return Response('hello') |
|
514 |
|
70acd2
|
515 |
You can use the :class:`~pyramid.view.view_config` decorator as a simple |
8a1b50
|
516 |
callable to manually decorate classes in Python 2.5 and below without the |
CD |
517 |
decorator syntactic sugar, if you wish: |
|
518 |
|
|
519 |
.. code-block:: python |
|
520 |
:linenos: |
|
521 |
|
|
522 |
from pyramid.response import Response |
|
523 |
from pyramid.view import view_config |
|
524 |
|
|
525 |
class MyView(object): |
|
526 |
def __init__(self, request): |
|
527 |
self.request = request |
|
528 |
|
|
529 |
def __call__(self): |
|
530 |
return Response('hello') |
|
531 |
|
|
532 |
my_view = view_config()(MyView) |
|
533 |
|
70acd2
|
534 |
More than one :class:`~pyramid.view.view_config` decorator can be stacked on |
8a1b50
|
535 |
top of any number of others. Each decorator creates a separate view |
CD |
536 |
registration. For example: |
|
537 |
|
|
538 |
.. code-block:: python |
|
539 |
:linenos: |
|
540 |
|
|
541 |
from pyramid.view import view_config |
|
542 |
from pyramid.response import Response |
|
543 |
|
|
544 |
@view_config(name='edit') |
|
545 |
@view_config(name='change') |
|
546 |
def edit(request): |
|
547 |
return Response('edited!') |
|
548 |
|
|
549 |
This registers the same view under two different names. |
|
550 |
|
2e3f70
|
551 |
The decorator can also be used against a method of a class: |
8a1b50
|
552 |
|
CD |
553 |
.. code-block:: python |
|
554 |
:linenos: |
|
555 |
|
|
556 |
from pyramid.response import Response |
|
557 |
from pyramid.view import view_config |
|
558 |
|
|
559 |
class MyView(object): |
|
560 |
def __init__(self, request): |
|
561 |
self.request = request |
|
562 |
|
|
563 |
@view_config(name='hello') |
|
564 |
def amethod(self): |
|
565 |
return Response('hello') |
|
566 |
|
2e3f70
|
567 |
When the decorator is used against a method of a class, a view is registered |
CZ |
568 |
for the *class*, so the class constructor must accept an argument list in one |
|
569 |
of two forms: either it must accept a single argument ``request`` or it must |
8a1b50
|
570 |
accept two arguments, ``context, request``. |
CD |
571 |
|
|
572 |
The method which is decorated must return a :term:`response`. |
|
573 |
|
|
574 |
Using the decorator against a particular method of a class is equivalent to |
|
575 |
using the ``attr`` parameter in a decorator attached to the class itself. |
|
576 |
For example, the above registration implied by the decorator being used |
|
577 |
against the ``amethod`` method could be spelled equivalently as the below: |
|
578 |
|
|
579 |
.. code-block:: python |
|
580 |
:linenos: |
|
581 |
|
|
582 |
from pyramid.response import Response |
|
583 |
from pyramid.view import view_config |
|
584 |
|
|
585 |
@view_config(attr='amethod', name='hello') |
|
586 |
class MyView(object): |
|
587 |
def __init__(self, request): |
|
588 |
self.request = request |
|
589 |
|
|
590 |
def amethod(self): |
|
591 |
return Response('hello') |
|
592 |
|
|
593 |
.. index:: |
|
594 |
single: add_view |
|
595 |
|
|
596 |
.. _mapping_views_using_imperative_config_section: |
|
597 |
|
e81ad8
|
598 |
Adding View Configuration Using :meth:`~pyramid.config.Configurator.add_view` |
CM |
599 |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
8a1b50
|
600 |
|
CD |
601 |
The :meth:`pyramid.config.Configurator.add_view` method within |
026da8
|
602 |
:ref:`configuration_module` is used to configure a view "imperatively" |
e81ad8
|
603 |
(without a :class:`~pyramid.view.view_config` decorator). The arguments to |
026da8
|
604 |
this method are very similar to the arguments that you provide to the |
CM |
605 |
:class:`~pyramid.view.view_config` decorator. For example: |
8a1b50
|
606 |
|
CD |
607 |
.. code-block:: python |
|
608 |
:linenos: |
|
609 |
|
|
610 |
from pyramid.response import Response |
|
611 |
|
|
612 |
def hello_world(request): |
|
613 |
return Response('hello!') |
|
614 |
|
|
615 |
# config is assumed to be an instance of the |
|
616 |
# pyramid.config.Configurator class |
|
617 |
config.add_view(hello_world, name='hello.html') |
|
618 |
|
|
619 |
The first argument, ``view``, is required. It must either be a Python object |
|
620 |
which is the view itself or a :term:`dotted Python name` to such an object. |
026da8
|
621 |
In the above example, ``view`` is the ``hello_world`` function. All other |
CM |
622 |
arguments are optional. See :meth:`pyramid.config.Configurator.add_view` for |
|
623 |
more information. |
|
624 |
|
|
625 |
When you use only :meth:`~pyramid.config.Configurator.add_view` to add view |
|
626 |
configurations, you don't need to issue a :term:`scan` in order for the view |
|
627 |
configuration to take effect. |
f4fcd3
|
628 |
|
8a1b50
|
629 |
.. index:: |
CD |
630 |
single: resource interfaces |
|
631 |
|
|
632 |
.. _using_resource_interfaces: |
|
633 |
|
|
634 |
Using Resource Interfaces In View Configuration |
|
635 |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
636 |
|
|
637 |
Instead of registering your views with a ``context`` that names a Python |
|
638 |
resource *class*, you can optionally register a view callable with a |
|
639 |
``context`` which is an :term:`interface`. An interface can be attached |
|
640 |
arbitrarily to any resource object. View lookup treats context interfaces |
|
641 |
specially, and therefore the identity of a resource can be divorced from that |
|
642 |
of the class which implements it. As a result, associating a view with an |
|
643 |
interface can provide more flexibility for sharing a single view between two |
|
644 |
or more different implementations of a resource type. For example, if two |
|
645 |
resource objects of different Python class types share the same interface, |
|
646 |
you can use the same view configuration to specify both of them as a |
|
647 |
``context``. |
|
648 |
|
|
649 |
In order to make use of interfaces in your application during view dispatch, |
|
650 |
you must create an interface and mark up your resource classes or instances |
|
651 |
with interface declarations that refer to this interface. |
|
652 |
|
|
653 |
To attach an interface to a resource *class*, you define the interface and |
|
654 |
use the :func:`zope.interface.implements` function to associate the interface |
|
655 |
with the class. |
|
656 |
|
|
657 |
.. code-block:: python |
|
658 |
:linenos: |
|
659 |
|
|
660 |
from zope.interface import Interface |
|
661 |
from zope.interface import implements |
|
662 |
|
|
663 |
class IHello(Interface): |
|
664 |
""" A marker interface """ |
|
665 |
|
|
666 |
class Hello(object): |
|
667 |
implements(IHello) |
|
668 |
|
|
669 |
To attach an interface to a resource *instance*, you define the interface and |
|
670 |
use the :func:`zope.interface.alsoProvides` function to associate the |
|
671 |
interface with the instance. This function mutates the instance in such a |
|
672 |
way that the interface is attached to it. |
|
673 |
|
|
674 |
.. code-block:: python |
|
675 |
:linenos: |
|
676 |
|
|
677 |
from zope.interface import Interface |
|
678 |
from zope.interface import alsoProvides |
|
679 |
|
|
680 |
class IHello(Interface): |
|
681 |
""" A marker interface """ |
|
682 |
|
|
683 |
class Hello(object): |
|
684 |
pass |
|
685 |
|
|
686 |
def make_hello(): |
|
687 |
hello = Hello() |
|
688 |
alsoProvides(hello, IHello) |
|
689 |
return hello |
|
690 |
|
|
691 |
Regardless of how you associate an interface, with a resource instance, or a |
|
692 |
resource class, the resulting code to associate that interface with a view |
|
693 |
callable is the same. Assuming the above code that defines an ``IHello`` |
|
694 |
interface lives in the root of your application, and its module is named |
|
695 |
"resources.py", the interface declaration below will associate the |
|
696 |
``mypackage.views.hello_world`` view with resources that implement, or |
|
697 |
provide, this interface. |
|
698 |
|
|
699 |
.. code-block:: python |
|
700 |
:linenos: |
|
701 |
|
|
702 |
# config is an instance of pyramid.config.Configurator |
|
703 |
|
|
704 |
config.add_view('mypackage.views.hello_world', name='hello.html', |
|
705 |
context='mypackage.resources.IHello') |
|
706 |
|
|
707 |
Any time a resource that is determined to be the :term:`context` provides |
|
708 |
this interface, and a view named ``hello.html`` is looked up against it as |
|
709 |
per the URL, the ``mypackage.views.hello_world`` view callable will be |
|
710 |
invoked. |
|
711 |
|
|
712 |
Note, in cases where a view is registered against a resource class, and a |
|
713 |
view is also registered against an interface that the resource class |
|
714 |
implements, an ambiguity arises. Views registered for the resource class take |
|
715 |
precedence over any views registered for any interface the resource class |
|
716 |
implements. Thus, if one view configuration names a ``context`` of both the |
|
717 |
class type of a resource, and another view configuration names a ``context`` |
|
718 |
of interface implemented by the resource's class, and both view |
|
719 |
configurations are otherwise identical, the view registered for the context's |
|
720 |
class will "win". |
|
721 |
|
|
722 |
For more information about defining resources with interfaces for use within |
|
723 |
view configuration, see :ref:`resources_which_implement_interfaces`. |
|
724 |
|
|
725 |
.. index:: |
|
726 |
single: view security |
|
727 |
pair: security; view |
|
728 |
|
|
729 |
.. _view_security_section: |
|
730 |
|
|
731 |
Configuring View Security |
|
732 |
~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
733 |
|
|
734 |
If an :term:`authorization policy` is active, any :term:`permission` attached |
|
735 |
to a :term:`view configuration` found during view lookup will be verified. |
|
736 |
This will ensure that the currently authenticated user possesses that |
|
737 |
permission against the :term:`context` resource before the view function is |
|
738 |
actually called. Here's an example of specifying a permission in a view |
70acd2
|
739 |
configuration using :meth:`~pyramid.config.Configurator.add_view`: |
8a1b50
|
740 |
|
CD |
741 |
.. code-block:: python |
|
742 |
:linenos: |
|
743 |
|
|
744 |
# config is an instance of pyramid.config.Configurator |
|
745 |
|
|
746 |
config.add_view('myproject.views.add_entry', name='add.html', |
|
747 |
context='myproject.resources.IBlog', permission='add') |
|
748 |
|
|
749 |
When an :term:`authorization policy` is enabled, this view will be protected |
|
750 |
with the ``add`` permission. The view will *not be called* if the user does |
|
751 |
not possess the ``add`` permission relative to the current :term:`context`. |
|
752 |
Instead the :term:`forbidden view` result will be returned to the client as |
|
753 |
per :ref:`protecting_views`. |
|
754 |
|
|
755 |
.. index:: |
|
756 |
single: debugging not found errors |
|
757 |
single: not found error (debugging) |
|
758 |
|
|
759 |
.. _debug_notfound_section: |
|
760 |
|
|
761 |
:exc:`NotFound` Errors |
|
762 |
~~~~~~~~~~~~~~~~~~~~~~ |
|
763 |
|
|
764 |
It's useful to be able to debug :exc:`NotFound` error responses when they |
|
765 |
occur unexpectedly due to an application registry misconfiguration. To debug |
|
766 |
these errors, use the ``PYRAMID_DEBUG_NOTFOUND`` environment variable or the |
|
767 |
``debug_notfound`` configuration file setting. Details of why a view was not |
|
768 |
found will be printed to ``stderr``, and the browser representation of the |
|
769 |
error will include the same information. See :ref:`environment_chapter` for |
|
770 |
more information about how, and where to set these values. |
|
771 |
|
8abf0a
|
772 |
.. index:: |
e573d4
|
773 |
single: HTTP caching |
CM |
774 |
|
|
775 |
.. _influencing_http_caching: |
|
776 |
|
|
777 |
Influencing HTTP Caching |
|
778 |
------------------------ |
|
779 |
|
|
780 |
.. note:: This feature is new in Pyramid 1.1. |
|
781 |
|
|
782 |
When a non-``None`` ``http_cache`` argument is passed to a view |
|
783 |
configuration, Pyramid will set ``Expires`` and ``Cache-Control`` response |
|
784 |
headers in the resulting response, causing browsers to cache the response |
|
785 |
data for some time. See ``http_cache`` in :ref:`nonpredicate_view_args` for |
|
786 |
the its allowable values and what they mean. |
|
787 |
|
|
788 |
Sometimes it's undesirable to have these headers set as the result of |
|
789 |
returning a response from a view, even though you'd like to decorate the view |
|
790 |
with a view configuration decorator that has ``http_cache``. Perhaps there's |
|
791 |
an alternate branch in your view code that returns a response that should |
|
792 |
never be cacheable, while the "normal" branch returns something that should |
|
793 |
always be cacheable. If this is the case, set the ``prevent_auto`` attribute |
|
794 |
of the ``response.cache_control`` object to a non-``False`` value. For |
|
795 |
example, the below view callable is configured with a ``@view_config`` |
|
796 |
decorator that indicates any response from the view should be cached for 3600 |
|
797 |
seconds. However, the view itself prevents caching from taking place unless |
|
798 |
there's a ``should_cache`` GET or POST variable: |
|
799 |
|
|
800 |
.. code-block:: python |
|
801 |
|
|
802 |
from pyramid.view import view_config |
|
803 |
|
|
804 |
@view_config(http_cache=3600) |
|
805 |
def view(request): |
|
806 |
response = Response() |
|
807 |
if not 'should_cache' in request.params: |
|
808 |
response.cache_control.prevent_auto = True |
|
809 |
return response |
|
810 |
|
|
811 |
Note that the ``http_cache`` machinery will overwrite or add to caching |
|
812 |
headers you set within the view itself unless you use ``preserve_auto``. |
|
813 |
|
|
814 |
You can also turn of the effect of ``http_cache`` entirely for the duration |
|
815 |
of a Pyramid application lifetime. To do so, set the |
|
816 |
``PYRAMID_PREVENT_HTTP_CACHE`` environment variable or the |
|
817 |
``prevent_http_cache`` configuration value setting to a true value. For more |
|
818 |
information, see :ref:`preventing_http_caching`. |
|
819 |
|
5fa17f
|
820 |
Note that setting ``prevent_http_cache`` will have no effect on caching |
CM |
821 |
headers that your application code itself sets. It will only prevent caching |
|
822 |
headers that would have been set by the Pyramid HTTP caching machinery |
|
823 |
invoked as the result of the ``http_cache`` argument to view configuration. |
|
824 |
|
e573d4
|
825 |
.. index:: |
8abf0a
|
826 |
pair: matching views; printing |
C |
827 |
single: paster pviews |
|
828 |
|
|
829 |
.. _displaying_matching_views: |
|
830 |
|
|
831 |
Displaying Matching Views for a Given URL |
|
832 |
----------------------------------------- |
|
833 |
|
|
834 |
For a big application with several views, it can be hard to keep the view |
|
835 |
configuration details in your head, even if you defined all the views |
|
836 |
yourself. You can use the ``paster pviews`` command in a terminal window to |
|
837 |
print a summary of matching routes and views for a given URL in your |
9e7162
|
838 |
application. The ``paster pviews`` command accepts two arguments. The |
MM |
839 |
first argument to ``pviews`` is the path to your application's ``.ini`` file |
|
840 |
and section name inside the ``.ini`` file which points to your application. |
|
841 |
This should be of the format ``config_file#section_name``. The second argument |
|
842 |
is the URL to test for matching views. |
8abf0a
|
843 |
|
C |
844 |
Here is an example for a simple view configuration using :term:`traversal`: |
|
845 |
|
|
846 |
.. code-block:: text |
|
847 |
:linenos: |
|
848 |
|
|
849 |
$ ../bin/paster pviews development.ini tutorial /FrontPage |
|
850 |
|
|
851 |
URL = /FrontPage |
|
852 |
|
|
853 |
context: <tutorial.models.Page object at 0xa12536c> |
2e3f70
|
854 |
view name: |
8abf0a
|
855 |
|
C |
856 |
View: |
|
857 |
----- |
|
858 |
tutorial.views.view_page |
|
859 |
required permission = view |
|
860 |
|
|
861 |
The output always has the requested URL at the top and below that all the |
|
862 |
views that matched with their view configuration details. In this example |
|
863 |
only one view matches, so there is just a single *View* section. For each |
|
864 |
matching view, the full code path to the associated view callable is shown, |
|
865 |
along with any permissions and predicates that are part of that view |
|
866 |
configuration. |
|
867 |
|
|
868 |
A more complex configuration might generate something like this: |
|
869 |
|
|
870 |
.. code-block:: text |
|
871 |
:linenos: |
|
872 |
|
9e7162
|
873 |
$ ../bin/paster pviews development.ini#shootout /about |
8abf0a
|
874 |
|
C |
875 |
URL = /about |
|
876 |
|
|
877 |
context: <shootout.models.RootFactory object at 0xa56668c> |
|
878 |
view name: about |
|
879 |
|
|
880 |
Route: |
|
881 |
------ |
|
882 |
route name: about |
|
883 |
route pattern: /about |
|
884 |
route path: /about |
2e3f70
|
885 |
subpath: |
8abf0a
|
886 |
route predicates (request method = GET) |
C |
887 |
|
|
888 |
View: |
|
889 |
----- |
|
890 |
shootout.views.about_view |
|
891 |
required permission = view |
|
892 |
view predicates (request_param testing, header X/header) |
|
893 |
|
|
894 |
Route: |
|
895 |
------ |
|
896 |
route name: about_post |
|
897 |
route pattern: /about |
|
898 |
route path: /about |
2e3f70
|
899 |
subpath: |
8abf0a
|
900 |
route predicates (request method = POST) |
C |
901 |
|
|
902 |
View: |
|
903 |
----- |
|
904 |
shootout.views.about_view_post |
|
905 |
required permission = view |
|
906 |
view predicates (request_param test) |
|
907 |
|
|
908 |
View: |
|
909 |
----- |
|
910 |
shootout.views.about_view_post2 |
|
911 |
required permission = view |
|
912 |
view predicates (request_param test2) |
|
913 |
|
|
914 |
In this case, we are dealing with a :term:`URL dispatch` application. This |
|
915 |
specific URL has two matching routes. The matching route information is |
|
916 |
displayed first, followed by any views that are associated with that route. |
|
917 |
As you can see from the second matching route output, a route can be |
|
918 |
associated with more than one view. |
|
919 |
|
|
920 |
For a URL that doesn't match any views, ``paster pviews`` will simply print |
|
921 |
out a *Not found* message. |
|
922 |
|