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 |
|
803817
|
13 |
:term:`View lookup` is the :app:`Pyramid` subsystem responsible for finding and |
SP |
14 |
invoking a :term:`view callable`. :term:`View configuration` controls how |
e81ad8
|
15 |
:term:`view lookup` operates in your application. During any given request, |
CM |
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 |
|
6ce1e0
|
23 |
.. index:: |
CM |
24 |
pair: resource; mapping to view callable |
|
25 |
pair: URL pattern; mapping to view callable |
|
26 |
|
8a1b50
|
27 |
Mapping a Resource or URL Pattern to a View Callable |
CD |
28 |
---------------------------------------------------- |
|
29 |
|
|
30 |
A developer makes a :term:`view callable` available for use within a |
|
31 |
:app:`Pyramid` application via :term:`view configuration`. A view |
|
32 |
configuration associates a view callable with a set of statements that |
803817
|
33 |
determine the set of circumstances which must be true for the view callable to |
SP |
34 |
be invoked. |
8a1b50
|
35 |
|
CD |
36 |
A view configuration statement is made about information present in the |
e8c66a
|
37 |
:term:`context` resource (or exception) and the :term:`request`. |
8a1b50
|
38 |
|
026da8
|
39 |
View configuration is performed in one of two ways: |
8a1b50
|
40 |
|
03e38b
|
41 |
- By running a :term:`scan` against application source code which has a |
8a1b50
|
42 |
:class:`pyramid.view.view_config` decorator attached to a Python object as |
70acd2
|
43 |
per :ref:`mapping_views_using_a_decorator_section`. |
8a1b50
|
44 |
|
03e38b
|
45 |
- By using the :meth:`pyramid.config.Configurator.add_view` method as per |
8a1b50
|
46 |
:ref:`mapping_views_using_imperative_config_section`. |
6ce1e0
|
47 |
|
CM |
48 |
.. index:: |
|
49 |
single: view configuration parameters |
8a1b50
|
50 |
|
CD |
51 |
.. _view_configuration_parameters: |
|
52 |
|
|
53 |
View Configuration Parameters |
|
54 |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
55 |
|
|
56 |
All forms of view configuration accept the same general types of arguments. |
|
57 |
|
|
58 |
Many arguments supplied during view configuration are :term:`view predicate` |
803817
|
59 |
arguments. View predicate arguments used during view configuration are used to |
SP |
60 |
narrow the set of circumstances in which :term:`view lookup` will find a |
2e3f70
|
61 |
particular view callable. |
8a1b50
|
62 |
|
e81ad8
|
63 |
:term:`View predicate` attributes are an important part of view configuration |
CM |
64 |
that enables the :term:`view lookup` subsystem to find and invoke the |
803817
|
65 |
appropriate view. The greater the number of predicate attributes possessed by |
SP |
66 |
a view's configuration, the more specific the circumstances need to be before |
|
67 |
the registered view callable will be invoked. The fewer the number of |
|
68 |
predicates which are supplied to a particular view configuration, the more |
|
69 |
likely it is that the associated view callable will be invoked. A view with |
|
70 |
five predicates will always be found and evaluated before a view with two, for |
1fbbb4
|
71 |
example. |
8a1b50
|
72 |
|
803817
|
73 |
This does not mean however, that :app:`Pyramid` "stops looking" when it finds a |
SP |
74 |
view registration with predicates that don't match. If one set of view |
|
75 |
predicates does not match, the "next most specific" view (if any) is consulted |
|
76 |
for predicates, and so on, until a view is found, or no view can be matched up |
|
77 |
with the request. The first view with a set of predicates all of which match |
|
78 |
the request environment will be invoked. |
8a1b50
|
79 |
|
CD |
80 |
If no view can be found with predicates which allow it to be matched up with |
|
81 |
the request, :app:`Pyramid` will return an error to the user's browser, |
|
82 |
representing a "not found" (404) page. See :ref:`changing_the_notfound_view` |
cec2b0
|
83 |
for more information about changing the default :term:`Not Found View`. |
8a1b50
|
84 |
|
803817
|
85 |
Other view configuration arguments are non-predicate arguments. These tend to |
SP |
86 |
modify the response of the view callable or prevent the view callable from |
8a1b50
|
87 |
being invoked due to an authorization policy. The presence of non-predicate |
CD |
88 |
arguments in a view configuration does not narrow the circumstances in which |
|
89 |
the view callable will be invoked. |
|
90 |
|
e573d4
|
91 |
.. _nonpredicate_view_args: |
CM |
92 |
|
8a1b50
|
93 |
Non-Predicate Arguments |
CD |
94 |
+++++++++++++++++++++++ |
|
95 |
|
|
96 |
``permission`` |
|
97 |
The name of a :term:`permission` that the user must possess in order to |
803817
|
98 |
invoke the :term:`view callable`. See :ref:`view_security_section` for more |
SP |
99 |
information about view security and permissions. |
2e3f70
|
100 |
|
803817
|
101 |
If ``permission`` is not supplied, no permission is registered for this view |
SP |
102 |
(it's accessible by any caller). |
8a1b50
|
103 |
|
CD |
104 |
``attr`` |
|
105 |
The view machinery defaults to using the ``__call__`` method of the |
|
106 |
:term:`view callable` (or the function itself, if the view callable is a |
|
107 |
function) to obtain a response. The ``attr`` value allows you to vary the |
803817
|
108 |
method attribute used to obtain the response. For example, if your view was |
SP |
109 |
a class, and the class has a method named ``index`` and you wanted to use |
|
110 |
this method instead of the class's ``__call__`` method to return the |
|
111 |
response, you'd say ``attr="index"`` in the view configuration for the view. |
|
112 |
This is most useful when the view definition is a class. |
8a1b50
|
113 |
|
CD |
114 |
If ``attr`` is not supplied, ``None`` is used (implying the function itself |
803817
|
115 |
if the view is a function, or the ``__call__`` callable attribute if the view |
SP |
116 |
is a class). |
8a1b50
|
117 |
|
CD |
118 |
``renderer`` |
803817
|
119 |
Denotes the :term:`renderer` implementation which will be used to construct a |
SP |
120 |
:term:`response` from the associated view callable's return value. |
1395f5
|
121 |
|
2033ee
|
122 |
.. seealso:: See also :ref:`renderers_chapter`. |
8a1b50
|
123 |
|
803817
|
124 |
This is either a single string term (e.g., ``json``) or a string implying a |
SP |
125 |
path or :term:`asset specification` (e.g., ``templates/views.pt``) naming a |
|
126 |
:term:`renderer` implementation. If the ``renderer`` value does not contain |
|
127 |
a dot (``.``), the specified string will be used to look up a renderer |
|
128 |
implementation, and that renderer implementation will be used to construct a |
|
129 |
response from the view return value. If the ``renderer`` value contains a |
|
130 |
dot (``.``), the specified term will be treated as a path, and the filename |
|
131 |
extension of the last element in the path will be used to look up the |
|
132 |
renderer implementation, which will be passed the full path. |
8a1b50
|
133 |
|
803817
|
134 |
When the renderer is a path—although a path is usually just a simple relative |
SP |
135 |
pathname (e.g., ``templates/foo.pt``, implying that a template named "foo.pt" |
|
136 |
is in the "templates" directory relative to the directory of the current |
5af300
|
137 |
:term:`package`)—the path can be absolute, starting with a slash on Unix or a |
803817
|
138 |
drive letter prefix on Windows. The path can alternatively be a :term:`asset |
SP |
139 |
specification` in the form ``some.dotted.package_name:relative/path``, making |
|
140 |
it possible to address template assets which live in a separate package. |
8a1b50
|
141 |
|
CD |
142 |
The ``renderer`` attribute is optional. If it is not defined, the "null" |
|
143 |
renderer is assumed (no rendering is performed and the value is passed back |
803817
|
144 |
to the upstream :app:`Pyramid` machinery unchanged). Note that if the view |
SP |
145 |
callable itself returns a :term:`response` (see :ref:`the_response`), the |
|
146 |
specified renderer implementation is never called. |
8a1b50
|
147 |
|
0fa199
|
148 |
``http_cache`` |
CM |
149 |
When you supply an ``http_cache`` value to a view configuration, the |
|
150 |
``Expires`` and ``Cache-Control`` headers of a response generated by the |
|
151 |
associated view callable are modified. The value for ``http_cache`` may be |
|
152 |
one of the following: |
|
153 |
|
803817
|
154 |
- A nonzero integer. If it's a nonzero integer, it's treated as a number of |
SP |
155 |
seconds. This number of seconds will be used to compute the ``Expires`` |
|
156 |
header and the ``Cache-Control: max-age`` parameter of responses to |
|
157 |
requests which call this view. For example: ``http_cache=3600`` instructs |
|
158 |
the requesting browser to 'cache this response for an hour, please'. |
0fa199
|
159 |
|
CM |
160 |
- A ``datetime.timedelta`` instance. If it's a ``datetime.timedelta`` |
803817
|
161 |
instance, it will be converted into a number of seconds, and that number of |
SP |
162 |
seconds will be used to compute the ``Expires`` header and the |
0fa199
|
163 |
``Cache-Control: max-age`` parameter of responses to requests which call |
CM |
164 |
this view. For example: ``http_cache=datetime.timedelta(days=1)`` |
|
165 |
instructs the requesting browser to 'cache this response for a day, |
|
166 |
please'. |
|
167 |
|
803817
|
168 |
- Zero (``0``). If the value is zero, the ``Cache-Control`` and ``Expires`` |
SP |
169 |
headers present in all responses from this view will be composed such that |
|
170 |
client browser cache (and any intermediate caches) are instructed to never |
|
171 |
cache the response. |
0fa199
|
172 |
|
803817
|
173 |
- A two-tuple. If it's a two-tuple (e.g., ``http_cache=(1, |
SP |
174 |
{'public':True})``), the first value in the tuple may be a nonzero integer |
|
175 |
or a ``datetime.timedelta`` instance. In either case this value will be |
|
176 |
used as the number of seconds to cache the response. The second value in |
|
177 |
the tuple must be a dictionary. The values present in the dictionary will |
|
178 |
be used as input to the ``Cache-Control`` response header. For example: |
|
179 |
``http_cache=(3600, {'public':True})`` means 'cache for an hour, and add |
|
180 |
``public`` to the Cache-Control header of the response'. All keys and |
|
181 |
values supported by the ``webob.cachecontrol.CacheControl`` interface may |
|
182 |
be added to the dictionary. Supplying ``{'public':True}`` is equivalent to |
|
183 |
calling ``response.cache_control.public = True``. |
0fa199
|
184 |
|
CM |
185 |
Providing a non-tuple value as ``http_cache`` is equivalent to calling |
|
186 |
``response.cache_expires(value)`` within your view's body. |
|
187 |
|
|
188 |
Providing a two-tuple value as ``http_cache`` is equivalent to calling |
|
189 |
``response.cache_expires(value[0], **value[1])`` within your view's body. |
|
190 |
|
803817
|
191 |
If you wish to avoid influencing the ``Expires`` header, and instead wish to |
SP |
192 |
only influence ``Cache-Control`` headers, pass a tuple as ``http_cache`` with |
|
193 |
the first element of ``None``, i.e., ``(None, {'public':True})``. |
0fa199
|
194 |
|
769da1
|
195 |
|
MM |
196 |
``require_csrf`` |
|
197 |
|
21d5be
|
198 |
CSRF checks will affect any request method that is not defined as a "safe" |
DS |
199 |
method by RFC2616. In pratice this means that GET, HEAD, OPTIONS, and TRACE |
|
200 |
methods will pass untouched and all others methods will require CSRF. This |
|
201 |
option is used in combination with the ``pyramid.require_default_csrf`` |
|
202 |
setting to control which request parameters are checked for CSRF tokens. |
769da1
|
203 |
|
MM |
204 |
This feature requires a configured :term:`session factory`. |
|
205 |
|
|
206 |
If this option is set to ``True`` then CSRF checks will be enabled for POST |
|
207 |
requests to this view. The required token will be whatever was specified by |
|
208 |
the ``pyramid.require_default_csrf`` setting, or will fallback to |
|
209 |
``csrf_token``. |
|
210 |
|
|
211 |
If this option is set to a string then CSRF checks will be enabled and it |
|
212 |
will be used as the required token regardless of the |
|
213 |
``pyramid.require_default_csrf`` setting. |
|
214 |
|
|
215 |
If this option is set to ``False`` then CSRF checks will be disabled |
|
216 |
regardless of the ``pyramid.require_default_csrf`` setting. |
|
217 |
|
65dee6
|
218 |
In addition, if this option is set to ``True`` or a string then CSRF origin |
DS |
219 |
checking will be enabled. |
|
220 |
|
769da1
|
221 |
See :ref:`auto_csrf_checking` for more information. |
MM |
222 |
|
|
223 |
.. versionadded:: 1.7 |
|
224 |
|
8a1b50
|
225 |
``wrapper`` |
263715
|
226 |
The :term:`view name` of a different :term:`view configuration` which will |
SP |
227 |
receive the response body of this view as the ``request.wrapped_body`` |
|
228 |
attribute of its own :term:`request`, and the :term:`response` returned by |
|
229 |
this view as the ``request.wrapped_response`` attribute of its own request. |
|
230 |
Using a wrapper makes it possible to "chain" views together to form a |
|
231 |
composite response. The response of the outermost wrapper view will be |
|
232 |
returned to the user. The wrapper view will be found as any view is found. |
|
233 |
See :ref:`view_lookup`. The "best" wrapper view will be found based on the |
|
234 |
lookup ordering. "Under the hood" this wrapper view is looked up via |
|
235 |
``pyramid.view.render_view_to_response(context, request, |
|
236 |
'wrapper_viewname')``. The context and request of a wrapper view is the same |
|
237 |
context and request of the inner view. |
8a1b50
|
238 |
|
263715
|
239 |
If ``wrapper`` is not supplied, no wrapper view is used. |
8a1b50
|
240 |
|
f7f0dd
|
241 |
``decorator`` |
86fc0c
|
242 |
A :term:`dotted Python name` to a function (or the function itself) which |
803817
|
243 |
will be used to decorate the registered :term:`view callable`. The decorator |
SP |
244 |
function will be called with the view callable as a single argument. The |
|
245 |
view callable it is passed will accept ``(context, request)``. The decorator |
|
246 |
must return a replacement view callable which also accepts ``(context, |
|
247 |
request)``. The ``decorator`` may also be an iterable of decorators, in which |
|
248 |
case they will be applied one after the other to the view, in reverse order. |
|
249 |
For example:: |
df6065
|
250 |
|
MM |
251 |
@view_config(..., decorator=(decorator2, decorator1)) |
|
252 |
def myview(request): |
|
253 |
... |
|
254 |
|
663c26
|
255 |
Is similar to decorating the view callable directly:: |
df6065
|
256 |
|
MM |
257 |
@view_config(...) |
|
258 |
@decorator2 |
|
259 |
@decorator1 |
|
260 |
def myview(request): |
|
261 |
... |
2e3f70
|
262 |
|
663c26
|
263 |
An important distinction is that each decorator will receive a response |
MM |
264 |
object implementing :class:`pyramid.interfaces.IResponse` instead of the |
|
265 |
raw value returned from the view callable. All decorators in the chain must |
|
266 |
return a response object or raise an exception: |
6e0f02
|
267 |
|
MM |
268 |
.. code-block:: python |
|
269 |
|
6517a9
|
270 |
def log_timer(wrapped): |
SP |
271 |
def wrapper(context, request): |
|
272 |
start = time.time() |
|
273 |
response = wrapped(context, request) |
|
274 |
duration = time.time() - start |
|
275 |
response.headers['X-View-Time'] = '%.3f' % (duration,) |
|
276 |
log.info('view took %.3f seconds', duration) |
|
277 |
return response |
|
278 |
return wrapper |
6e0f02
|
279 |
|
f7f0dd
|
280 |
``mapper`` |
CM |
281 |
A Python object or :term:`dotted Python name` which refers to a :term:`view |
|
282 |
mapper`, or ``None``. By default it is ``None``, which indicates that the |
|
283 |
view should use the default view mapper. This plug-point is useful for |
803817
|
284 |
Pyramid extension developers, but it's not very useful for "civilians" who |
f7f0dd
|
285 |
are just developing stock Pyramid applications. Pay no attention to the man |
CM |
286 |
behind the curtain. |
|
287 |
|
121f45
|
288 |
``exception_only`` |
MM |
289 |
|
|
290 |
When this value is ``True``, the ``context`` argument must be a subclass of |
|
291 |
``Exception``. This flag indicates that only an :term:`exception view` should |
|
292 |
be created, and that this view should not match if the traversal |
|
293 |
:term:`context` matches the ``context`` argument. If the ``context`` is a |
|
294 |
subclass of ``Exception`` and this value is ``False`` (the default), then a |
|
295 |
view will be registered to match the traversal :term:`context` as well. |
|
296 |
|
|
297 |
.. versionadded:: 1.8 |
|
298 |
|
8a1b50
|
299 |
Predicate Arguments |
CD |
300 |
+++++++++++++++++++ |
|
301 |
|
803817
|
302 |
These arguments modify view lookup behavior. In general the more predicate |
SP |
303 |
arguments that are supplied, the more specific and narrower the usage of the |
8a1b50
|
304 |
configured view. |
CD |
305 |
|
|
306 |
``name`` |
8cb682
|
307 |
The :term:`view name` required to match this view callable. A ``name`` |
803817
|
308 |
argument is typically only used when your application uses :term:`traversal`. |
SP |
309 |
Read :ref:`traversal_chapter` to understand the concept of a view name. |
8a1b50
|
310 |
|
CD |
311 |
If ``name`` is not supplied, the empty string is used (implying the default |
|
312 |
view). |
|
313 |
|
|
314 |
``context`` |
803817
|
315 |
An object representing a Python class of which the :term:`context` resource |
SP |
316 |
must be an instance *or* the :term:`interface` that the :term:`context` |
8a1b50
|
317 |
resource must provide in order for this view to be found and called. This |
CD |
318 |
predicate is true when the :term:`context` resource is an instance of the |
803817
|
319 |
represented class or if the :term:`context` resource provides the represented |
SP |
320 |
interface; it is otherwise false. |
8a1b50
|
321 |
|
e8c66a
|
322 |
It is possible to pass an exception class as the context if your context may |
160aab
|
323 |
subclass an exception. In this case *two* views will be registered. One |
SP |
324 |
will match normal incoming requests, and the other will match as an |
e8c66a
|
325 |
:term:`exception view` which only occurs when an exception is raised during |
MM |
326 |
the normal request processing pipeline. |
|
327 |
|
8a1b50
|
328 |
If ``context`` is not supplied, the value ``None``, which matches any |
CD |
329 |
resource, is used. |
|
330 |
|
|
331 |
``route_name`` |
|
332 |
If ``route_name`` is supplied, the view callable will be invoked only when |
|
333 |
the named route has matched. |
|
334 |
|
|
335 |
This value must match the ``name`` of a :term:`route configuration` |
803817
|
336 |
declaration (see :ref:`urldispatch_chapter`) that must match before this view |
SP |
337 |
will be called. Note that the ``route`` configuration referred to by |
8a1b50
|
338 |
``route_name`` will usually have a ``*traverse`` token in the value of its |
CD |
339 |
``pattern``, representing a part of the path that will be used by |
|
340 |
:term:`traversal` against the result of the route's :term:`root factory`. |
|
341 |
|
2e3f70
|
342 |
If ``route_name`` is not supplied, the view callable will only have a chance |
8a1b50
|
343 |
of being invoked if no other route was matched. This is when the |
803817
|
344 |
request/context pair found via :term:`resource location` does not indicate it |
SP |
345 |
matched any configured route. |
121f45
|
346 |
|
MM |
347 |
``accept`` |
|
348 |
A :term:`media type` that will be matched against the ``Accept`` HTTP request header. |
|
349 |
If this value is specified, it must be a specific media type, such as ``text/html``. |
|
350 |
If the media type is acceptable by the ``Accept`` header of the request, or if the ``Accept`` header isn't set at all in the request, this predicate will match. |
|
351 |
If this does not match the ``Accept`` header of the request, view matching continues. |
|
352 |
|
|
353 |
If ``accept`` is not specified, the ``HTTP_ACCEPT`` HTTP header is not taken into consideration when deciding whether or not to invoke the associated view callable. |
|
354 |
|
f081ae
|
355 |
See :ref:`accept_content_negotiation` for more information. |
121f45
|
356 |
|
MM |
357 |
.. versionchanged:: 1.10 |
|
358 |
Media ranges such as ``text/*`` will now raise :class:`pyramid.exceptions.ConfigurationError`. |
|
359 |
Previously these values had undefined behavior based on the version of WebOb being used and was never fully supported. |
8a1b50
|
360 |
|
CD |
361 |
``request_type`` |
|
362 |
This value should be an :term:`interface` that the :term:`request` must |
|
363 |
provide in order for this view to be found and called. |
|
364 |
|
803817
|
365 |
If ``request_type`` is not supplied, the value ``None`` is used, implying any |
SP |
366 |
request type. |
8a1b50
|
367 |
|
CD |
368 |
*This is an advanced feature, not often used by "civilians"*. |
|
369 |
|
|
370 |
``request_method`` |
306c29
|
371 |
This value can be either a string (such as ``"GET"``, ``"POST"``, |
803817
|
372 |
``"PUT"``, ``"DELETE"``, ``"HEAD"``, or ``"OPTIONS"``) representing an HTTP |
SP |
373 |
``REQUEST_METHOD`` or a tuple containing one or more of these strings. A |
|
374 |
view declaration with this argument ensures that the view will only be called |
|
375 |
when the ``method`` attribute of the request (i.e., the ``REQUEST_METHOD`` of |
|
376 |
the WSGI environment) matches a supplied value. |
f016cd
|
377 |
|
803817
|
378 |
.. versionchanged:: 1.4 |
SP |
379 |
The use of ``"GET"`` also implies that the view will respond to ``"HEAD"``. |
8a1b50
|
380 |
|
803817
|
381 |
If ``request_method`` is not supplied, the view will be invoked regardless of |
SP |
382 |
the ``REQUEST_METHOD`` of the :term:`WSGI` environment. |
8a1b50
|
383 |
|
CD |
384 |
``request_param`` |
a62912
|
385 |
This value can be any string or a sequence of strings. A view declaration |
SP |
386 |
with this argument ensures that the view will only be called when the |
|
387 |
:term:`request` has a key in the ``request.params`` dictionary (an HTTP |
803817
|
388 |
``GET`` or ``POST`` variable) that has a name which matches the supplied |
SP |
389 |
value. |
8a1b50
|
390 |
|
803817
|
391 |
If any value supplied has an ``=`` sign in it, e.g., |
SP |
392 |
``request_param="foo=123"``, then the key (``foo``) must both exist in the |
|
393 |
``request.params`` dictionary, *and* the value must match the right hand side |
|
394 |
of the expression (``123``) for the view to "match" the current request. |
8a1b50
|
395 |
|
CD |
396 |
If ``request_param`` is not supplied, the view will be invoked without |
|
397 |
consideration of keys and values in the ``request.params`` dictionary. |
|
398 |
|
c0e6e6
|
399 |
``match_param`` |
803817
|
400 |
This param may be either a single string of the format "key=value" or a tuple |
SP |
401 |
containing one or more of these strings. |
c0e6e6
|
402 |
|
CM |
403 |
This argument ensures that the view will only be called when the |
803817
|
404 |
:term:`request` has key/value pairs in its :term:`matchdict` that equal those |
SP |
405 |
supplied in the predicate. For example, ``match_param="action=edit"`` would |
c0e6e6
|
406 |
require the ``action`` parameter in the :term:`matchdict` match the right |
dd1c53
|
407 |
hand side of the expression (``edit``) for the view to "match" the current |
c0e6e6
|
408 |
request. |
CM |
409 |
|
803817
|
410 |
If the ``match_param`` is a tuple, every key/value pair must match for the |
SP |
411 |
predicate to pass. |
c0e6e6
|
412 |
|
CM |
413 |
If ``match_param`` is not supplied, the view will be invoked without |
|
414 |
consideration of the keys and values in ``request.matchdict``. |
a62912
|
415 |
|
SP |
416 |
.. versionadded:: 1.2 |
c0e6e6
|
417 |
|
8a1b50
|
418 |
``containment`` |
803817
|
419 |
This value should be a reference to a Python class or :term:`interface` that |
SP |
420 |
a parent object in the context resource's :term:`lineage` must provide in |
|
421 |
order for this view to be found and called. The resources in your resource |
|
422 |
tree must be "location-aware" to use this feature. |
8a1b50
|
423 |
|
803817
|
424 |
If ``containment`` is not supplied, the interfaces and classes in the lineage |
SP |
425 |
are not considered when deciding whether or not to invoke the view callable. |
8a1b50
|
426 |
|
CD |
427 |
See :ref:`location_aware` for more information about location-awareness. |
|
428 |
|
|
429 |
``xhr`` |
|
430 |
This value should be either ``True`` or ``False``. If this value is |
|
431 |
specified and is ``True``, the :term:`WSGI` environment must possess an |
803817
|
432 |
``HTTP_X_REQUESTED_WITH`` header (i.e., ``X-Requested-With``) that has the |
8a1b50
|
433 |
value ``XMLHttpRequest`` for the associated view callable to be found and |
CD |
434 |
called. This is useful for detecting AJAX requests issued from jQuery, |
803817
|
435 |
Prototype, and other Javascript libraries. |
8a1b50
|
436 |
|
803817
|
437 |
If ``xhr`` is not specified, the ``HTTP_X_REQUESTED_WITH`` HTTP header is not |
SP |
438 |
taken into consideration when deciding whether or not to invoke the |
8a1b50
|
439 |
associated view callable. |
CD |
440 |
|
|
441 |
``header`` |
|
442 |
This value represents an HTTP header name or a header name/value pair. |
|
443 |
|
|
444 |
If ``header`` is specified, it must be a header name or a |
|
445 |
``headername:headervalue`` pair. |
|
446 |
|
803817
|
447 |
If ``header`` is specified without a value (a bare header name only, e.g., |
SP |
448 |
``If-Modified-Since``), the view will only be invoked if the HTTP header |
|
449 |
exists with any value in the request. |
8a1b50
|
450 |
|
803817
|
451 |
If ``header`` is specified, and possesses a name/value pair (e.g., |
SP |
452 |
``User-Agent:Mozilla/.*``), the view will only be invoked if the HTTP header |
|
453 |
exists *and* the HTTP header matches the value requested. When the |
|
454 |
``headervalue`` contains a ``:`` (colon), it will be considered a name/value |
|
455 |
pair (e.g., ``User-Agent:Mozilla/.*`` or ``Host:localhost``). The value |
|
456 |
portion should be a regular expression. |
8a1b50
|
457 |
|
CD |
458 |
Whether or not the value represents a header name or a header name/value |
|
459 |
pair, the case of the header name is not significant. |
|
460 |
|
803817
|
461 |
If ``header`` is not specified, the composition, presence, or absence of HTTP |
SP |
462 |
headers is not taken into consideration when deciding whether or not to |
|
463 |
invoke the associated view callable. |
8a1b50
|
464 |
|
CD |
465 |
``path_info`` |
|
466 |
This value represents a regular expression pattern that will be tested |
803817
|
467 |
against the ``PATH_INFO`` WSGI environment variable to decide whether or not |
SP |
468 |
to call the associated view callable. If the regex matches, this predicate |
|
469 |
will be ``True``. |
8a1b50
|
470 |
|
CD |
471 |
If ``path_info`` is not specified, the WSGI ``PATH_INFO`` is not taken into |
|
472 |
consideration when deciding whether or not to invoke the associated view |
|
473 |
callable. |
|
474 |
|
643a83
|
475 |
``check_csrf`` |
803817
|
476 |
If specified, this value should be one of ``None``, ``True``, ``False``, or a |
SP |
477 |
string representing the "check name". If the value is ``True`` or a string, |
|
478 |
CSRF checking will be performed. If the value is ``False`` or ``None``, CSRF |
|
479 |
checking will not be performed. |
643a83
|
480 |
|
803817
|
481 |
If the value provided is a string, that string will be used as the "check |
SP |
482 |
name". If the value provided is ``True``, ``csrf_token`` will be used as the |
|
483 |
check name. |
643a83
|
484 |
|
CM |
485 |
If CSRF checking is performed, the checked value will be the value of |
f12005
|
486 |
``request.POST[check_name]``. This value will be compared against the |
643a83
|
487 |
value of ``request.session.get_csrf_token()``, and the check will pass if |
803817
|
488 |
these two values are the same. If the check passes, the associated view will |
SP |
489 |
be permitted to execute. If the check fails, the associated view will not be |
|
490 |
permitted to execute. |
643a83
|
491 |
|
803817
|
492 |
Note that using this feature requires a :term:`session factory` to have been |
SP |
493 |
configured. |
643a83
|
494 |
|
CM |
495 |
.. versionadded:: 1.4a2 |
|
496 |
|
c25a8f
|
497 |
``physical_path`` |
CM |
498 |
If specified, this value should be a string or a tuple representing the |
|
499 |
:term:`physical path` of the context found via traversal for this predicate |
803817
|
500 |
to match as true. For example, ``physical_path='/'``, |
SP |
501 |
``physical_path='/a/b/c'``, or ``physical_path=('', 'a', 'b', 'c')``. This |
|
502 |
is not a path prefix match or a regex, but a whole-path match. It's useful |
c25a8f
|
503 |
when you want to always potentially show a view when some object is traversed |
CM |
504 |
to, but you can't be sure about what kind of object it will be, so you can't |
803817
|
505 |
use the ``context`` predicate. The individual path elements between slash |
c25a8f
|
506 |
characters or in tuple elements should be the Unicode representation of the |
CM |
507 |
name of the resource and should not be encoded in any way. |
|
508 |
|
|
509 |
.. versionadded:: 1.4a3 |
|
510 |
|
c7337b
|
511 |
``effective_principals`` |
CM |
512 |
If specified, this value should be a :term:`principal` identifier or a |
|
513 |
sequence of principal identifiers. If the |
803817
|
514 |
:meth:`pyramid.request.Request.effective_principals` method indicates that |
SP |
515 |
every principal named in the argument list is present in the current request, |
|
516 |
this predicate will return True; otherwise it will return False. For |
|
517 |
example: ``effective_principals=pyramid.security.Authenticated`` or |
c7337b
|
518 |
``effective_principals=('fred', 'group:admins')``. |
CM |
519 |
|
|
520 |
.. versionadded:: 1.4a4 |
|
521 |
|
8a1b50
|
522 |
``custom_predicates`` |
803817
|
523 |
If ``custom_predicates`` is specified, it must be a sequence of references to |
SP |
524 |
custom predicate callables. Use custom predicates when no set of predefined |
|
525 |
predicates do what you need. Custom predicates can be combined with |
|
526 |
predefined predicates as necessary. Each custom predicate callable should |
|
527 |
accept two arguments, ``context`` and ``request``, and should return either |
|
528 |
``True`` or ``False`` after doing arbitrary evaluation of the context |
|
529 |
resource and/or the request. If all callables return ``True``, the |
8a1b50
|
530 |
associated view callable will be considered viable for a given request. |
CD |
531 |
|
803817
|
532 |
If ``custom_predicates`` is not specified, no custom predicates are used. |
8a1b50
|
533 |
|
643a83
|
534 |
``predicates`` |
CM |
535 |
Pass a key/value pair here to use a third-party predicate registered via |
|
536 |
:meth:`pyramid.config.Configurator.add_view_predicate`. More than one |
|
537 |
key/value pair can be used at the same time. See |
|
538 |
:ref:`view_and_route_predicates` for more information about third-party |
|
539 |
predicates. |
|
540 |
|
|
541 |
.. versionadded:: 1.4a1 |
|
542 |
|
aa7b06
|
543 |
Inverting Predicate Values |
CM |
544 |
++++++++++++++++++++++++++ |
|
545 |
|
|
546 |
You can invert the meaning of any predicate value by wrapping it in a call to |
|
547 |
:class:`pyramid.config.not_`. |
|
548 |
|
|
549 |
.. code-block:: python |
6517a9
|
550 |
:linenos: |
aa7b06
|
551 |
|
6517a9
|
552 |
from pyramid.config import not_ |
aa7b06
|
553 |
|
6517a9
|
554 |
config.add_view( |
SP |
555 |
'mypackage.views.my_view', |
|
556 |
route_name='ok', |
|
557 |
request_method=not_('POST') |
|
558 |
) |
aa7b06
|
559 |
|
803817
|
560 |
The above example will ensure that the view is called if the request method is |
SP |
561 |
*not* ``POST``, at least if no other view is more specific. |
aa7b06
|
562 |
|
CM |
563 |
This technique of wrapping a predicate value in ``not_`` can be used anywhere |
|
564 |
predicate values are accepted: |
|
565 |
|
|
566 |
- :meth:`pyramid.config.Configurator.add_view` |
|
567 |
|
|
568 |
- :meth:`pyramid.view.view_config` |
|
569 |
|
|
570 |
.. versionadded:: 1.5 |
|
571 |
|
|
572 |
|
8a1b50
|
573 |
.. index:: |
CD |
574 |
single: view_config decorator |
|
575 |
|
|
576 |
.. _mapping_views_using_a_decorator_section: |
|
577 |
|
e81ad8
|
578 |
Adding View Configuration Using the ``@view_config`` Decorator |
CM |
579 |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
8a1b50
|
580 |
|
CD |
581 |
.. warning:: |
|
582 |
|
803817
|
583 |
Using this feature tends to slow down application startup slightly, as more |
SP |
584 |
work is performed at application startup to scan for view configuration |
|
585 |
declarations. For maximum startup performance, use the view configuration |
|
586 |
method described in :ref:`mapping_views_using_imperative_config_section` |
|
587 |
instead. |
8a1b50
|
588 |
|
e81ad8
|
589 |
The :class:`~pyramid.view.view_config` decorator can be used to associate |
CM |
590 |
:term:`view configuration` information with a function, method, or class that |
|
591 |
acts as a :app:`Pyramid` view callable. |
8a1b50
|
592 |
|
026da8
|
593 |
Here's an example of the :class:`~pyramid.view.view_config` decorator that |
CM |
594 |
lives within a :app:`Pyramid` application module ``views.py``: |
8a1b50
|
595 |
|
CD |
596 |
.. code-block:: python |
6517a9
|
597 |
:linenos: |
8a1b50
|
598 |
|
6517a9
|
599 |
from resources import MyResource |
SP |
600 |
from pyramid.view import view_config |
|
601 |
from pyramid.response import Response |
8a1b50
|
602 |
|
6517a9
|
603 |
@view_config(route_name='ok', request_method='POST', permission='read') |
SP |
604 |
def my_view(request): |
|
605 |
return Response('OK') |
8a1b50
|
606 |
|
CD |
607 |
Using this decorator as above replaces the need to add this imperative |
|
608 |
configuration stanza: |
|
609 |
|
|
610 |
.. code-block:: python |
6517a9
|
611 |
:linenos: |
8a1b50
|
612 |
|
6517a9
|
613 |
config.add_view('mypackage.views.my_view', route_name='ok', |
SP |
614 |
request_method='POST', permission='read') |
8a1b50
|
615 |
|
CD |
616 |
All arguments to ``view_config`` may be omitted. For example: |
|
617 |
|
|
618 |
.. code-block:: python |
6517a9
|
619 |
:linenos: |
8a1b50
|
620 |
|
6517a9
|
621 |
from pyramid.response import Response |
SP |
622 |
from pyramid.view import view_config |
8a1b50
|
623 |
|
6517a9
|
624 |
@view_config() |
SP |
625 |
def my_view(request): |
|
626 |
""" My view """ |
|
627 |
return Response() |
8a1b50
|
628 |
|
CD |
629 |
Such a registration as the one directly above implies that the view name will |
|
630 |
be ``my_view``, registered with a ``context`` argument that matches any |
|
631 |
resource type, using no permission, registered against requests with any |
|
632 |
request method, request type, request param, route name, or containment. |
|
633 |
|
|
634 |
The mere existence of a ``@view_config`` decorator doesn't suffice to perform |
|
635 |
view configuration. All that the decorator does is "annotate" the function |
|
636 |
with your configuration declarations, it doesn't process them. To make |
803817
|
637 |
:app:`Pyramid` process your :class:`pyramid.view.view_config` declarations, you |
SP |
638 |
*must* use the ``scan`` method of a :class:`pyramid.config.Configurator`: |
8a1b50
|
639 |
|
CD |
640 |
.. code-block:: python |
6517a9
|
641 |
:linenos: |
8a1b50
|
642 |
|
6517a9
|
643 |
# config is assumed to be an instance of the |
SP |
644 |
# pyramid.config.Configurator class |
|
645 |
config.scan() |
8a1b50
|
646 |
|
803817
|
647 |
Please see :ref:`decorations_and_code_scanning` for detailed information about |
SP |
648 |
what happens when code is scanned for configuration declarations resulting from |
|
649 |
use of decorators like :class:`~pyramid.view.view_config`. |
8a1b50
|
650 |
|
CD |
651 |
See :ref:`configuration_module` for additional API arguments to the |
70acd2
|
652 |
:meth:`~pyramid.config.Configurator.scan` method. For example, the method |
8a1b50
|
653 |
allows you to supply a ``package`` argument to better control exactly *which* |
CD |
654 |
code will be scanned. |
e81ad8
|
655 |
|
CM |
656 |
All arguments to the :class:`~pyramid.view.view_config` decorator mean |
803817
|
657 |
precisely the same thing as they would if they were passed as arguments to the |
SP |
658 |
:meth:`pyramid.config.Configurator.add_view` method save for the ``view`` |
|
659 |
argument. Usage of the :class:`~pyramid.view.view_config` decorator is a form |
|
660 |
of :term:`declarative configuration`, while |
e81ad8
|
661 |
:meth:`pyramid.config.Configurator.add_view` is a form of :term:`imperative |
CM |
662 |
configuration`. However, they both do the same thing. |
8a1b50
|
663 |
|
6ce1e0
|
664 |
.. index:: |
CM |
665 |
single: view_config placement |
|
666 |
|
bb93cb
|
667 |
.. _view_config_placement: |
CM |
668 |
|
8a1b50
|
669 |
``@view_config`` Placement |
CD |
670 |
++++++++++++++++++++++++++ |
|
671 |
|
70acd2
|
672 |
A :class:`~pyramid.view.view_config` decorator can be placed in various points |
8a1b50
|
673 |
in your application. |
CD |
674 |
|
|
675 |
If your view callable is a function, it may be used as a function decorator: |
|
676 |
|
|
677 |
.. code-block:: python |
6517a9
|
678 |
:linenos: |
8a1b50
|
679 |
|
6517a9
|
680 |
from pyramid.view import view_config |
SP |
681 |
from pyramid.response import Response |
8a1b50
|
682 |
|
6517a9
|
683 |
@view_config(route_name='edit') |
SP |
684 |
def edit(request): |
|
685 |
return Response('edited!') |
8a1b50
|
686 |
|
CD |
687 |
If your view callable is a class, the decorator can also be used as a class |
803817
|
688 |
decorator. All the arguments to the decorator are the same when applied against |
SP |
689 |
a class as when they are applied against a function. For example: |
8a1b50
|
690 |
|
CD |
691 |
.. code-block:: python |
6517a9
|
692 |
:linenos: |
8a1b50
|
693 |
|
6517a9
|
694 |
from pyramid.response import Response |
SP |
695 |
from pyramid.view import view_config |
8a1b50
|
696 |
|
6517a9
|
697 |
@view_config(route_name='hello') |
SP |
698 |
class MyView(object): |
|
699 |
def __init__(self, request): |
|
700 |
self.request = request |
8a1b50
|
701 |
|
6517a9
|
702 |
def __call__(self): |
SP |
703 |
return Response('hello') |
8a1b50
|
704 |
|
70acd2
|
705 |
More than one :class:`~pyramid.view.view_config` decorator can be stacked on |
8a1b50
|
706 |
top of any number of others. Each decorator creates a separate view |
CD |
707 |
registration. For example: |
|
708 |
|
|
709 |
.. code-block:: python |
6517a9
|
710 |
:linenos: |
8a1b50
|
711 |
|
6517a9
|
712 |
from pyramid.view import view_config |
SP |
713 |
from pyramid.response import Response |
8a1b50
|
714 |
|
6517a9
|
715 |
@view_config(route_name='edit') |
SP |
716 |
@view_config(route_name='change') |
|
717 |
def edit(request): |
|
718 |
return Response('edited!') |
8a1b50
|
719 |
|
CD |
720 |
This registers the same view under two different names. |
|
721 |
|
2e3f70
|
722 |
The decorator can also be used against a method of a class: |
8a1b50
|
723 |
|
CD |
724 |
.. code-block:: python |
6517a9
|
725 |
:linenos: |
8a1b50
|
726 |
|
6517a9
|
727 |
from pyramid.response import Response |
SP |
728 |
from pyramid.view import view_config |
8a1b50
|
729 |
|
6517a9
|
730 |
class MyView(object): |
SP |
731 |
def __init__(self, request): |
|
732 |
self.request = request |
8a1b50
|
733 |
|
6517a9
|
734 |
@view_config(route_name='hello') |
SP |
735 |
def amethod(self): |
|
736 |
return Response('hello') |
8a1b50
|
737 |
|
2e3f70
|
738 |
When the decorator is used against a method of a class, a view is registered |
CZ |
739 |
for the *class*, so the class constructor must accept an argument list in one |
803817
|
740 |
of two forms: either a single argument, ``request``, or two arguments, |
SP |
741 |
``context, request``. |
8a1b50
|
742 |
|
CD |
743 |
The method which is decorated must return a :term:`response`. |
|
744 |
|
|
745 |
Using the decorator against a particular method of a class is equivalent to |
803817
|
746 |
using the ``attr`` parameter in a decorator attached to the class itself. For |
SP |
747 |
example, the above registration implied by the decorator being used against the |
|
748 |
``amethod`` method could be written equivalently as follows: |
8a1b50
|
749 |
|
CD |
750 |
.. code-block:: python |
6517a9
|
751 |
:linenos: |
8a1b50
|
752 |
|
6517a9
|
753 |
from pyramid.response import Response |
SP |
754 |
from pyramid.view import view_config |
8a1b50
|
755 |
|
6517a9
|
756 |
@view_config(attr='amethod', route_name='hello') |
SP |
757 |
class MyView(object): |
|
758 |
def __init__(self, request): |
|
759 |
self.request = request |
8a1b50
|
760 |
|
6517a9
|
761 |
def amethod(self): |
SP |
762 |
return Response('hello') |
8a1b50
|
763 |
|
4375cf
|
764 |
|
8a1b50
|
765 |
.. index:: |
CD |
766 |
single: add_view |
|
767 |
|
|
768 |
.. _mapping_views_using_imperative_config_section: |
|
769 |
|
e81ad8
|
770 |
Adding View Configuration Using :meth:`~pyramid.config.Configurator.add_view` |
CM |
771 |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
8a1b50
|
772 |
|
CD |
773 |
The :meth:`pyramid.config.Configurator.add_view` method within |
803817
|
774 |
:ref:`configuration_module` is used to configure a view "imperatively" (without |
SP |
775 |
a :class:`~pyramid.view.view_config` decorator). The arguments to this method |
|
776 |
are very similar to the arguments that you provide to the |
026da8
|
777 |
:class:`~pyramid.view.view_config` decorator. For example: |
8a1b50
|
778 |
|
CD |
779 |
.. code-block:: python |
6517a9
|
780 |
:linenos: |
8a1b50
|
781 |
|
6517a9
|
782 |
from pyramid.response import Response |
8a1b50
|
783 |
|
6517a9
|
784 |
def hello_world(request): |
SP |
785 |
return Response('hello!') |
8a1b50
|
786 |
|
6517a9
|
787 |
# config is assumed to be an instance of the |
SP |
788 |
# pyramid.config.Configurator class |
|
789 |
config.add_view(hello_world, route_name='hello') |
8a1b50
|
790 |
|
803817
|
791 |
The first argument, a :term:`view callable`, is the only required argument. It |
SP |
792 |
must either be a Python object which is the view itself or a :term:`dotted |
|
793 |
Python name` to such an object. In the above example, the ``view callable`` is |
|
794 |
the ``hello_world`` function. |
026da8
|
795 |
|
CM |
796 |
When you use only :meth:`~pyramid.config.Configurator.add_view` to add view |
|
797 |
configurations, you don't need to issue a :term:`scan` in order for the view |
|
798 |
configuration to take effect. |
8a1b50
|
799 |
|
CD |
800 |
.. index:: |
4375cf
|
801 |
single: view_defaults class decorator |
CM |
802 |
|
|
803 |
.. _view_defaults: |
|
804 |
|
|
805 |
``@view_defaults`` Class Decorator |
|
806 |
---------------------------------- |
|
807 |
|
40dbf4
|
808 |
.. versionadded:: 1.3 |
4375cf
|
809 |
|
CM |
810 |
If you use a class as a view, you can use the |
|
811 |
:class:`pyramid.view.view_defaults` class decorator on the class to provide |
|
812 |
defaults to the view configuration information used by every ``@view_config`` |
|
813 |
decorator that decorates a method of that class. |
|
814 |
|
|
815 |
For instance, if you've got a class that has methods that represent "REST |
803817
|
816 |
actions", all of which are mapped to the same route but different request |
4375cf
|
817 |
methods, instead of this: |
CM |
818 |
|
|
819 |
.. code-block:: python |
6517a9
|
820 |
:linenos: |
4375cf
|
821 |
|
6517a9
|
822 |
from pyramid.view import view_config |
SP |
823 |
from pyramid.response import Response |
4375cf
|
824 |
|
6517a9
|
825 |
class RESTView(object): |
SP |
826 |
def __init__(self, request): |
|
827 |
self.request = request |
4375cf
|
828 |
|
6517a9
|
829 |
@view_config(route_name='rest', request_method='GET') |
SP |
830 |
def get(self): |
|
831 |
return Response('get') |
4375cf
|
832 |
|
6517a9
|
833 |
@view_config(route_name='rest', request_method='POST') |
SP |
834 |
def post(self): |
|
835 |
return Response('post') |
4375cf
|
836 |
|
6517a9
|
837 |
@view_config(route_name='rest', request_method='DELETE') |
SP |
838 |
def delete(self): |
|
839 |
return Response('delete') |
4375cf
|
840 |
|
CM |
841 |
You can do this: |
|
842 |
|
|
843 |
.. code-block:: python |
6517a9
|
844 |
:linenos: |
4375cf
|
845 |
|
6517a9
|
846 |
from pyramid.view import view_defaults |
SP |
847 |
from pyramid.view import view_config |
|
848 |
from pyramid.response import Response |
4375cf
|
849 |
|
6517a9
|
850 |
@view_defaults(route_name='rest') |
SP |
851 |
class RESTView(object): |
|
852 |
def __init__(self, request): |
|
853 |
self.request = request |
4375cf
|
854 |
|
6517a9
|
855 |
@view_config(request_method='GET') |
SP |
856 |
def get(self): |
|
857 |
return Response('get') |
4375cf
|
858 |
|
6517a9
|
859 |
@view_config(request_method='POST') |
SP |
860 |
def post(self): |
|
861 |
return Response('post') |
4375cf
|
862 |
|
6517a9
|
863 |
@view_config(request_method='DELETE') |
SP |
864 |
def delete(self): |
|
865 |
return Response('delete') |
4375cf
|
866 |
|
CM |
867 |
In the above example, we were able to take the ``route_name='rest'`` argument |
803817
|
868 |
out of the call to each individual ``@view_config`` statement because we used a |
SP |
869 |
``@view_defaults`` class decorator to provide the argument as a default to each |
|
870 |
view method it possessed. |
4375cf
|
871 |
|
CM |
872 |
Arguments passed to ``@view_config`` will override any default passed to |
|
873 |
``@view_defaults``. |
|
874 |
|
|
875 |
The ``view_defaults`` class decorator can also provide defaults to the |
|
876 |
:meth:`pyramid.config.Configurator.add_view` directive when a decorated class |
803817
|
877 |
is passed to that directive as its ``view`` argument. For example, instead of |
SP |
878 |
this: |
4375cf
|
879 |
|
CM |
880 |
.. code-block:: python |
6517a9
|
881 |
:linenos: |
4375cf
|
882 |
|
6517a9
|
883 |
from pyramid.response import Response |
SP |
884 |
from pyramid.config import Configurator |
4375cf
|
885 |
|
6517a9
|
886 |
class RESTView(object): |
SP |
887 |
def __init__(self, request): |
|
888 |
self.request = request |
4375cf
|
889 |
|
6517a9
|
890 |
def get(self): |
SP |
891 |
return Response('get') |
4375cf
|
892 |
|
6517a9
|
893 |
def post(self): |
SP |
894 |
return Response('post') |
4375cf
|
895 |
|
6517a9
|
896 |
def delete(self): |
SP |
897 |
return Response('delete') |
4375cf
|
898 |
|
6517a9
|
899 |
def main(global_config, **settings): |
SP |
900 |
config = Configurator() |
|
901 |
config.add_route('rest', '/rest') |
|
902 |
config.add_view( |
|
903 |
RESTView, route_name='rest', attr='get', request_method='GET') |
|
904 |
config.add_view( |
|
905 |
RESTView, route_name='rest', attr='post', request_method='POST') |
|
906 |
config.add_view( |
|
907 |
RESTView, route_name='rest', attr='delete', request_method='DELETE') |
|
908 |
return config.make_wsgi_app() |
4375cf
|
909 |
|
c40d20
|
910 |
To reduce the amount of repetition in the ``config.add_view`` statements, we |
1e35e0
|
911 |
can move the ``route_name='rest'`` argument to a ``@view_defaults`` class |
803817
|
912 |
decorator on the ``RESTView`` class: |
4375cf
|
913 |
|
CM |
914 |
.. code-block:: python |
6517a9
|
915 |
:linenos: |
4375cf
|
916 |
|
6517a9
|
917 |
from pyramid.view import view_defaults |
SP |
918 |
from pyramid.response import Response |
|
919 |
from pyramid.config import Configurator |
4375cf
|
920 |
|
6517a9
|
921 |
@view_defaults(route_name='rest') |
SP |
922 |
class RESTView(object): |
|
923 |
def __init__(self, request): |
|
924 |
self.request = request |
4375cf
|
925 |
|
6517a9
|
926 |
def get(self): |
SP |
927 |
return Response('get') |
4375cf
|
928 |
|
6517a9
|
929 |
def post(self): |
SP |
930 |
return Response('post') |
4375cf
|
931 |
|
6517a9
|
932 |
def delete(self): |
SP |
933 |
return Response('delete') |
4375cf
|
934 |
|
6517a9
|
935 |
def main(global_config, **settings): |
SP |
936 |
config = Configurator() |
|
937 |
config.add_route('rest', '/rest') |
|
938 |
config.add_view(RESTView, attr='get', request_method='GET') |
|
939 |
config.add_view(RESTView, attr='post', request_method='POST') |
|
940 |
config.add_view(RESTView, attr='delete', request_method='DELETE') |
|
941 |
return config.make_wsgi_app() |
4375cf
|
942 |
|
CM |
943 |
:class:`pyramid.view.view_defaults` accepts the same set of arguments that |
|
944 |
:class:`pyramid.view.view_config` does, and they have the same meaning. Each |
|
945 |
argument passed to ``view_defaults`` provides a default for the view |
|
946 |
configurations of methods of the class it's decorating. |
|
947 |
|
803817
|
948 |
Normal Python inheritance rules apply to defaults added via ``view_defaults``. |
SP |
949 |
For example: |
4375cf
|
950 |
|
CM |
951 |
.. code-block:: python |
6517a9
|
952 |
:linenos: |
4375cf
|
953 |
|
6517a9
|
954 |
@view_defaults(route_name='rest') |
SP |
955 |
class Foo(object): |
|
956 |
pass |
4375cf
|
957 |
|
6517a9
|
958 |
class Bar(Foo): |
SP |
959 |
pass |
4375cf
|
960 |
|
CM |
961 |
The ``Bar`` class above will inherit its view defaults from the arguments |
|
962 |
passed to the ``view_defaults`` decorator of the ``Foo`` class. To prevent |
803817
|
963 |
this from happening, use a ``view_defaults`` decorator without any arguments on |
SP |
964 |
the subclass: |
4375cf
|
965 |
|
CM |
966 |
.. code-block:: python |
6517a9
|
967 |
:linenos: |
4375cf
|
968 |
|
6517a9
|
969 |
@view_defaults(route_name='rest') |
SP |
970 |
class Foo(object): |
|
971 |
pass |
4375cf
|
972 |
|
6517a9
|
973 |
@view_defaults() |
SP |
974 |
class Bar(Foo): |
|
975 |
pass |
4375cf
|
976 |
|
CM |
977 |
The ``view_defaults`` decorator only works as a class decorator; using it |
|
978 |
against a function or a method will produce nonsensical results. |
|
979 |
|
|
980 |
.. index:: |
8a1b50
|
981 |
single: view security |
CD |
982 |
pair: security; view |
|
983 |
|
|
984 |
.. _view_security_section: |
|
985 |
|
|
986 |
Configuring View Security |
|
987 |
~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
988 |
|
|
989 |
If an :term:`authorization policy` is active, any :term:`permission` attached |
803817
|
990 |
to a :term:`view configuration` found during view lookup will be verified. This |
SP |
991 |
will ensure that the currently authenticated user possesses that permission |
|
992 |
against the :term:`context` resource before the view function is actually |
|
993 |
called. Here's an example of specifying a permission in a view configuration |
|
994 |
using :meth:`~pyramid.config.Configurator.add_view`: |
8a1b50
|
995 |
|
CD |
996 |
.. code-block:: python |
6517a9
|
997 |
:linenos: |
8a1b50
|
998 |
|
6517a9
|
999 |
# config is an instance of pyramid.config.Configurator |
8a1b50
|
1000 |
|
6517a9
|
1001 |
config.add_route('add', '/add.html', factory='mypackage.Blog') |
SP |
1002 |
config.add_view('myproject.views.add_entry', route_name='add', |
|
1003 |
permission='add') |
8a1b50
|
1004 |
|
CD |
1005 |
When an :term:`authorization policy` is enabled, this view will be protected |
|
1006 |
with the ``add`` permission. The view will *not be called* if the user does |
|
1007 |
not possess the ``add`` permission relative to the current :term:`context`. |
803817
|
1008 |
Instead the :term:`forbidden view` result will be returned to the client as per |
SP |
1009 |
:ref:`protecting_views`. |
8a1b50
|
1010 |
|
CD |
1011 |
.. index:: |
|
1012 |
single: debugging not found errors |
|
1013 |
single: not found error (debugging) |
|
1014 |
|
|
1015 |
.. _debug_notfound_section: |
|
1016 |
|
f758ec
|
1017 |
:exc:`~pyramid.exceptions.NotFound` Errors |
TL |
1018 |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
8a1b50
|
1019 |
|
803817
|
1020 |
It's useful to be able to debug :exc:`~pyramid.exceptions.NotFound` error |
SP |
1021 |
responses when they occur unexpectedly due to an application registry |
|
1022 |
misconfiguration. To debug these errors, use the ``PYRAMID_DEBUG_NOTFOUND`` |
|
1023 |
environment variable or the ``pyramid.debug_notfound`` configuration file |
|
1024 |
setting. Details of why a view was not found will be printed to ``stderr``, |
f016cd
|
1025 |
and the browser representation of the error will include the same information. |
803817
|
1026 |
See :ref:`environment_chapter` for more information about how, and where to set |
SP |
1027 |
these values. |
8a1b50
|
1028 |
|
8abf0a
|
1029 |
.. index:: |
30f79d
|
1030 |
single: Accept |
f081ae
|
1031 |
single: Accept content negotiation |
e573d4
|
1032 |
|
f081ae
|
1033 |
.. _accept_content_negotiation: |
121f45
|
1034 |
|
MM |
1035 |
Accept Header Content Negotiation |
|
1036 |
--------------------------------- |
|
1037 |
|
|
1038 |
The ``accept`` argument to :meth:`pyramid.config.Configurator.add_view` can be used to control :term:`view lookup` by dispatching to different views based on the HTTP ``Accept`` request header. |
ed6ddc
|
1039 |
Consider the example below in which there are three defined views. |
MM |
1040 |
Each view uses the ``Accept`` header to trigger an appropriate response renderer. |
121f45
|
1041 |
|
MM |
1042 |
.. code-block:: python |
|
1043 |
|
ed6ddc
|
1044 |
from pyramid.httpexceptions import HTTPNotAcceptable |
121f45
|
1045 |
from pyramid.view import view_config |
MM |
1046 |
|
|
1047 |
@view_config(accept='application/json', renderer='json') |
|
1048 |
@view_config(accept='text/html', renderer='templates/hello.jinja2') |
|
1049 |
def myview(request): |
|
1050 |
return { |
|
1051 |
'name': request.GET.get('name', 'bob'), |
|
1052 |
} |
|
1053 |
|
ed6ddc
|
1054 |
@view_config() |
MM |
1055 |
def myview_unacceptable(request): |
|
1056 |
raise HTTPNotAcceptable |
121f45
|
1057 |
|
MM |
1058 |
The appropriate view is selected here when the client specifies an unambiguous header such as ``Accept: text/*`` or ``Accept: application/json``. |
ed6ddc
|
1059 |
Similarly, if the client specifies a media type that no view is registered to handle, such as ``Accept: text/plain``, it will fall through to ``myview_unacceptable`` and raise ``406 Not Acceptable``. |
MM |
1060 |
There are a few cases in which the client may specify ambiguous constraints: |
|
1061 |
|
|
1062 |
- ``Accept: */*``. |
30f79d
|
1063 |
- More than one acceptable media type with the same quality. |
ed6ddc
|
1064 |
- A missing ``Accept`` header. |
MM |
1065 |
- An invalid ``Accept`` header. |
|
1066 |
|
30f79d
|
1067 |
In these cases the preferred view is not clearly defined (see :rfc:`7231#section-5.3.2`) and :app:`Pyramid` will select one semi-randomly. |
ed6ddc
|
1068 |
This can be controlled by telling :app:`Pyramid` what the preferred relative ordering is between various media types by using :meth:`pyramid.config.Configurator.add_accept_view_order`. |
121f45
|
1069 |
For example: |
MM |
1070 |
|
|
1071 |
.. code-block:: python |
|
1072 |
|
|
1073 |
from pyramid.config import Configurator |
|
1074 |
|
|
1075 |
def main(global_config, **settings): |
|
1076 |
config = Configurator(settings=settings) |
ed6ddc
|
1077 |
config.add_accept_view_order('text/html') |
MM |
1078 |
config.add_accept_view_order( |
121f45
|
1079 |
'application/json', |
MM |
1080 |
weighs_more_than='text/html', |
|
1081 |
) |
|
1082 |
config.scan() |
|
1083 |
return config.make_wsgi_app() |
|
1084 |
|
ed6ddc
|
1085 |
In this case, the ``application/json`` view should always be selected in cases where it is otherwise ambiguous. |
121f45
|
1086 |
|
f081ae
|
1087 |
.. index:: |
MM |
1088 |
single: default accept ordering |
|
1089 |
|
30f79d
|
1090 |
.. _default_accept_ordering: |
MM |
1091 |
|
ed6ddc
|
1092 |
Default Accept Ordering |
ae79df
|
1093 |
~~~~~~~~~~~~~~~~~~~~~~~ |
30f79d
|
1094 |
|
MM |
1095 |
:app:`Pyramid` will always sort multiple views with the same ``(name, context, route_name)`` first by the specificity of the ``accept`` offer. |
4a9f4f
|
1096 |
For any set of media type offers with the same ``type/subtype``, the offers with params will weigh more than the bare ``type/subtype`` offer. |
MM |
1097 |
This means that ``text/plain;charset=utf8`` will always be offered before ``text/plain``. |
30f79d
|
1098 |
|
4a9f4f
|
1099 |
By default, within a given ``type/subtype``, the order of offers is ambiguous. For example, ``text/plain;charset=utf8`` versus ``text/plain;charset=latin1`` are sorted in an unspecified way. Similarly, between media types the order is also unspecified other than the defaults described below. For example, ``image/jpeg`` versus ``image/png`` versus ``application/pdf``. In these cases, the ordering may be controlled using :meth:`pyramid.config.Configurator.add_accept_view_order`. For example, to sort ``text/plain`` higher than ``text/html`` and to prefer a ``charset=utf8`` versus a ``charset=latin-1`` within the ``text/plain`` media type: |
30f79d
|
1100 |
|
MM |
1101 |
.. code-block:: python |
|
1102 |
|
|
1103 |
config.add_accept_view_order('text/plain', weighs_more_than='text/html') |
|
1104 |
config.add_accept_view_order('text/plain;charset=utf8', weighs_more_than='text/plain;charset=latin-1') |
|
1105 |
|
4a9f4f
|
1106 |
It is an error to try and sort accept headers across levels of specificity. You can only sort a ``type/subtype`` against another ``type/subtype``, not against a ``type/subtype;params``. That ordering is a hard requirement. |
121f45
|
1107 |
|
ed6ddc
|
1108 |
By default, :app:`Pyramid` defines a very simple priority ordering for views that prefers human-readable responses over JSON: |
121f45
|
1109 |
|
ed6ddc
|
1110 |
- ``text/html`` |
MM |
1111 |
- ``application/xhtml+xml`` |
|
1112 |
- ``application/xml`` |
|
1113 |
- ``text/xml`` |
|
1114 |
- ``text/plain`` |
|
1115 |
- ``application/json`` |
|
1116 |
|
|
1117 |
API clients tend to be able to specify their desired headers with more control than web browsers, and can specify the correct ``Accept`` value, if necessary. |
|
1118 |
Therefore, the motivation for this ordering is to optimize for readability. |
|
1119 |
Media types that are not listed above are ordered randomly during :term:`view lookup` between otherwise-similar views. |
|
1120 |
The defaults can be overridden using :meth:`pyramid.config.Configurator.add_accept_view_order` as described above. |
121f45
|
1121 |
|
30f79d
|
1122 |
.. index:: |
MM |
1123 |
single: HTTP caching |
|
1124 |
|
e573d4
|
1125 |
.. _influencing_http_caching: |
CM |
1126 |
|
|
1127 |
Influencing HTTP Caching |
|
1128 |
------------------------ |
|
1129 |
|
40dbf4
|
1130 |
.. versionadded:: 1.1 |
e573d4
|
1131 |
|
803817
|
1132 |
When a non-``None`` ``http_cache`` argument is passed to a view configuration, |
SP |
1133 |
Pyramid will set ``Expires`` and ``Cache-Control`` response headers in the |
|
1134 |
resulting response, causing browsers to cache the response data for some time. |
|
1135 |
See ``http_cache`` in :ref:`nonpredicate_view_args` for the allowable values |
|
1136 |
and what they mean. |
e573d4
|
1137 |
|
803817
|
1138 |
Sometimes it's undesirable to have these headers set as the result of returning |
SP |
1139 |
a response from a view, even though you'd like to decorate the view with a view |
|
1140 |
configuration decorator that has ``http_cache``. Perhaps there's an |
|
1141 |
alternative branch in your view code that returns a response that should never |
|
1142 |
be cacheable, while the "normal" branch returns something that should always be |
|
1143 |
cacheable. If this is the case, set the ``prevent_auto`` attribute of the |
|
1144 |
``response.cache_control`` object to a non-``False`` value. For example, the |
|
1145 |
below view callable is configured with a ``@view_config`` decorator that |
|
1146 |
indicates any response from the view should be cached for 3600 seconds. |
|
1147 |
However, the view itself prevents caching from taking place unless there's a |
|
1148 |
``should_cache`` GET or POST variable: |
e573d4
|
1149 |
|
CM |
1150 |
.. code-block:: python |
|
1151 |
|
6517a9
|
1152 |
from pyramid.view import view_config |
e573d4
|
1153 |
|
6517a9
|
1154 |
@view_config(http_cache=3600) |
SP |
1155 |
def view(request): |
|
1156 |
response = Response() |
|
1157 |
if 'should_cache' not in request.params: |
|
1158 |
response.cache_control.prevent_auto = True |
|
1159 |
return response |
e573d4
|
1160 |
|
803817
|
1161 |
Note that the ``http_cache`` machinery will overwrite or add to caching headers |
SP |
1162 |
you set within the view itself, unless you use ``prevent_auto``. |
e573d4
|
1163 |
|
803817
|
1164 |
You can also turn off the effect of ``http_cache`` entirely for the duration of |
SP |
1165 |
a Pyramid application lifetime. To do so, set the |
e573d4
|
1166 |
``PYRAMID_PREVENT_HTTP_CACHE`` environment variable or the |
803817
|
1167 |
``pyramid.prevent_http_cache`` configuration value setting to a true value. For |
SP |
1168 |
more information, see :ref:`preventing_http_caching`. |
e573d4
|
1169 |
|
875ded
|
1170 |
Note that setting ``pyramid.prevent_http_cache`` will have no effect on caching |
5fa17f
|
1171 |
headers that your application code itself sets. It will only prevent caching |
803817
|
1172 |
headers that would have been set by the Pyramid HTTP caching machinery invoked |
SP |
1173 |
as the result of the ``http_cache`` argument to view configuration. |
5fa17f
|
1174 |
|
6ce1e0
|
1175 |
.. index:: |
CM |
1176 |
pair: view configuration; debugging |
|
1177 |
|
49d634
|
1178 |
.. _debugging_view_configuration: |
PE |
1179 |
|
8cb682
|
1180 |
Debugging View Configuration |
ae4c57
|
1181 |
---------------------------- |
8abf0a
|
1182 |
|
ae4c57
|
1183 |
See :ref:`displaying_matching_views` for information about how to display |
CM |
1184 |
each of the view callables that might match for a given URL. This can be an |
|
1185 |
effective way to figure out why a particular view callable is being called |
|
1186 |
instead of the one you'd like to be called. |