diff options
Diffstat (limited to 'docs/narr')
| -rw-r--r-- | docs/narr/hooks.rst | 110 | ||||
| -rw-r--r-- | docs/narr/introspector.rst | 15 | ||||
| -rw-r--r-- | docs/narr/renderers.rst | 2 | ||||
| -rw-r--r-- | docs/narr/urldispatch.rst | 141 |
4 files changed, 172 insertions, 96 deletions
diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index eaccc14a3..b7f052b00 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -19,24 +19,66 @@ found view`, which is a :term:`view callable`. A default notfound view exists. The default not found view can be overridden through application configuration. -The :term:`not found view` callable is a view callable like any other. The -:term:`view configuration` which causes it to be a "not found" view consists -only of naming the :exc:`pyramid.httpexceptions.HTTPNotFound` class as the -``context`` of the view configuration. - If your application uses :term:`imperative configuration`, you can replace -the Not Found view by using the :meth:`pyramid.config.Configurator.add_view` -method to register an "exception view": +the Not Found view by using the +:meth:`pyramid.config.Configurator.add_notfound_view` method: .. code-block:: python :linenos: - from pyramid.httpexceptions import HTTPNotFound - from helloworld.views import notfound_view - config.add_view(notfound_view, context=HTTPNotFound) + from helloworld.views import notfound + config.add_notfound_view(notfound) + +Replace ``helloworld.views.notfound`` with a reference to the :term:`view +callable` you want to use to represent the Not Found view. The :term:`not +found view` callable is a view callable like any other. + +If your application instead uses :class:`pyramid.view.view_config` decorators +and a :term:`scan`, you can replace the Not Found view by using the +:class:`pyramid.view.notfound_view_config` decorator: + +.. code-block:: python + :linenos: + + from pyramid.view import notfound_view_config + + notfound_view_config() + def notfound(request): + return Response('Not Found, dude', status='404 Not Found') + + def main(globals, **settings): + config = Configurator() + config.scan() + +This does exactly what the imperative example above showed. + +Your application can define *multiple* not found views if necessary. Both +:meth:`pyramid.config.Configurator.add_notfound_view` and +:class:`pyramid.view.notfound_view_config` take most of the same arguments as +:class:`pyramid.config.Configurator.add_view` and +:class:`pyramid.view.view_config`, respectively. This means that not found +views can carry predicates limiting their applicability. For example: + +.. code-block:: python + :linenos: + + from pyramid.view import notfound_view_config -Replace ``helloworld.views.notfound_view`` with a reference to the -:term:`view callable` you want to use to represent the Not Found view. + notfound_view_config(request_method='GET') + def notfound_get(request): + return Response('Not Found during GET, dude', status='404 Not Found') + + notfound_view_config(request_method='POST') + def notfound_post(request): + return Response('Not Found during POST, dude', status='404 Not Found') + + def main(globals, **settings): + config = Configurator() + config.scan() + +The ``notfound_get`` view will be called when a view could not be found and +the request method was ``GET``. The ``notfound_post`` view will be called +when a view could not be found and the request method was ``POST``. Like any other view, the notfound view must accept at least a ``request`` parameter, or both ``context`` and ``request``. The ``request`` is the @@ -45,6 +87,11 @@ used in the call signature) will be the instance of the :exc:`~pyramid.httpexceptions.HTTPNotFound` exception that caused the view to be called. +Both :meth:`pyramid.config.Configurator.add_notfound_view` and +:class:`pyramid.view.notfound_view_config` can be used to automatically +redirect requests to slash-appended routes. See +:ref:`redirecting_to_slash_appended_routes` for examples. + Here's some sample code that implements a minimal NotFound view callable: .. code-block:: python @@ -52,7 +99,7 @@ Here's some sample code that implements a minimal NotFound view callable: from pyramid.httpexceptions import HTTPNotFound - def notfound_view(request): + def notfound(request): return HTTPNotFound() .. note:: @@ -66,6 +113,14 @@ Here's some sample code that implements a minimal NotFound view callable: ``pyramid.debug_notfound`` environment setting is true than it is when it is false. +.. note:: + + Both :meth:`pyramid.config.Configurator.add_notfound_view` and + :class:`pyramid.view.notfound_view_config` are new as of Pyramid 1.3. + Older Pyramid documentation instructed users to use ``add_view`` instead, + with a ``context`` of ``HTTPNotFound``. This still works; the convenience + method and decorator are just wrappers around this functionality. + .. warning:: When a NotFound view callable accepts an argument list as @@ -90,23 +145,40 @@ the view which generates it can be overridden as necessary. The :term:`forbidden view` callable is a view callable like any other. The :term:`view configuration` which causes it to be a "forbidden" view consists -only of naming the :exc:`pyramid.httpexceptions.HTTPForbidden` class as the -``context`` of the view configuration. +of using the meth:`pyramid.config.Configurator.add_forbidden_view` API or the +:class:`pyramid.view.forbidden_view_config` decorator. -You can replace the forbidden view by using the -:meth:`pyramid.config.Configurator.add_view` method to register an "exception -view": +For example, you can add a forbidden view by using the +:meth:`pyramid.config.Configurator.add_forbidden_view` method to register a +forbidden view: .. code-block:: python :linenos: from helloworld.views import forbidden_view from pyramid.httpexceptions import HTTPForbidden - config.add_view(forbidden_view, context=HTTPForbidden) + config.add_forbidden_view(forbidden_view) Replace ``helloworld.views.forbidden_view`` with a reference to the Python :term:`view callable` you want to use to represent the Forbidden view. +If instead you prefer to use decorators and a :term:`scan`, you can use the +:class:`pyramid.view.forbidden_view_config` decorator to mark a view callable +as a forbidden view: + +.. code-block:: python + :linenos: + + from pyramid.view import forbidden_view_config + + forbidden_view_config() + def forbidden(request): + return Response('forbidden') + + def main(globals, **settings): + config = Configurator() + config.scan() + Like any other view, the forbidden view must accept at least a ``request`` parameter, or both ``context`` and ``request``. The ``context`` (available as ``request.context`` if you're using the request-only view argument diff --git a/docs/narr/introspector.rst b/docs/narr/introspector.rst index d465c47d9..74595cac8 100644 --- a/docs/narr/introspector.rst +++ b/docs/narr/introspector.rst @@ -576,17 +576,14 @@ relationships. It looks something like this: Disabling Introspection ----------------------- -You can disable Pyramid introspection by passing the object -:attr:`pyramid.registry.noop_introspector` to the :term:`Configurator` -constructor in your application setup: +You can disable Pyramid introspection by passing the flag +``introspection=False`` to the :term:`Configurator` constructor in your +application setup: .. code-block:: python from pyramid.config import Configurator - from pyramid.registry import noop_introspector - config = Configurator(..., introspector=noop_introspector) + config = Configurator(..., introspection=False) -When the noop introspector is active, all introspectables generated by -configuration directives are thrown away. A noop introspector behaves just -like a "real" introspector, but the methods of a noop introspector do nothing -and return null values. +When ``introspection`` is ``False``, all introspectables generated by +configuration directives are thrown away. diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index 1f1b1943b..76035cbdf 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -103,7 +103,7 @@ Likewise for an :term:`HTTP exception` response: .. code-block:: python :linenos: - from pyramid.httpexceptions import HTTPNotFound + from pyramid.httpexceptions import HTTPFound from pyramid.view import view_config @view_config(renderer='json') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index a7bf74786..7c0b437c1 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -772,95 +772,102 @@ ignored when ``static`` is ``True``. Redirecting to Slash-Appended Routes ------------------------------------ -For behavior like Django's ``APPEND_SLASH=True``, use the -:func:`~pyramid.view.append_slash_notfound_view` view as the :term:`Not Found -view` in your application. Defining this view as the :term:`Not Found view` -is a way to automatically redirect requests where the URL lacks a trailing -slash, but requires one to match the proper route. When configured, along -with at least one other route in your application, this view will be invoked -if the value of ``PATH_INFO`` does not already end in a slash, and if the -value of ``PATH_INFO`` *plus* a slash matches any route's pattern. In this -case it does an HTTP redirect to the slash-appended ``PATH_INFO``. - -Let's use an example, because this behavior is a bit magical. If the -``append_slash_notfound_view`` is configured in your application and your -route configuration looks like so: +For behavior like Django's ``APPEND_SLASH=True``, use the ``append_slash`` +argument to :meth:`pyramid.config.Configurator.add_notfound_view` or the +equivalent ``append_slash`` argument to the +:class:`pyramid.view.notfound_view_config` decorator. + +Adding ``append_slash=True`` is a way to automatically redirect requests +where the URL lacks a trailing slash, but requires one to match the proper +route. When configured, along with at least one other route in your +application, this view will be invoked if the value of ``PATH_INFO`` does not +already end in a slash, and if the value of ``PATH_INFO`` *plus* a slash +matches any route's pattern. In this case it does an HTTP redirect to the +slash-appended ``PATH_INFO``. + +To configure the slash-appending not found view in your application, change +the application's startup configuration, adding the following stanza: .. code-block:: python :linenos: - config.add_route('noslash', 'no_slash') - config.add_route('hasslash', 'has_slash/') +Let's use an example. If the following routes are configured in your +application: + +.. code-block:: python + :linenos: + + from pyramid.httpexceptions import HTTPNotFound + + def notfound(request): + return HTTPNotFound('Not found, bro.') + + def no_slash(request): + return Response('No slash') - config.add_view('myproject.views.no_slash', route_name='noslash') - config.add_view('myproject.views.has_slash', route_name='hasslash') + def has_slash(request): + return Response('Has slash') + + def main(g, **settings): + config = Configurator() + config.add_route('noslash', 'no_slash') + config.add_route('hasslash', 'has_slash/') + config.add_view(no_slash, route_name='noslash') + config.add_view(has_slash, route_name='hasslash') + config.add_notfound_view(notfound, append_slash=True) + +If a request enters the application with the ``PATH_INFO`` value of +``/no_slash``, the first route will match and the browser will show "No +slash". However, if a request enters the application with the ``PATH_INFO`` +value of ``/no_slash/``, *no* route will match, and the slash-appending not +found view will not find a matching route with an appended slash. As a +result, the ``notfound`` view will be called and it will return a "Not found, +bro." body. If a request enters the application with the ``PATH_INFO`` value of ``/has_slash/``, the second route will match. If a request enters the application with the ``PATH_INFO`` value of ``/has_slash``, a route *will* be found by the slash-appending not found view. An HTTP redirect to -``/has_slash/`` will be returned to the user's browser. +``/has_slash/`` will be returned to the user's browser. As a result, the +``notfound`` view will never actually be called. -If a request enters the application with the ``PATH_INFO`` value of -``/no_slash``, the first route will match. However, if a request enters the -application with the ``PATH_INFO`` value of ``/no_slash/``, *no* route will -match, and the slash-appending not found view will *not* find a matching -route with an appended slash. - -.. warning:: - - You **should not** rely on this mechanism to redirect ``POST`` requests. - The redirect of the slash-appending not found view will turn a ``POST`` - request into a ``GET``, losing any ``POST`` data in the original - request. - -To configure the slash-appending not found view in your application, change -the application's startup configuration, adding the following stanza: +The following application uses the :class:`pyramid.view.notfound_view_config` +and :class:`pyramid.view.view_config` decorators and a :term:`scan` to do +exactly the same job: .. code-block:: python :linenos: - config.add_view('pyramid.view.append_slash_notfound_view', - context='pyramid.httpexceptions.HTTPNotFound') - -See :ref:`view_module` and :ref:`changing_the_notfound_view` for more -information about the slash-appending not found view and for a more general -description of how to configure a not found view. + from pyramid.httpexceptions import HTTPNotFound + from pyramid.view import notfound_view_config, view_config -Custom Not Found View With Slash Appended Routes -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + @notfound_view_config(append_slash=True) + def notfound(request): + return HTTPNotFound('Not found, bro.') -There can only be one :term:`Not Found view` in any :app:`Pyramid` -application. Even if you use :func:`~pyramid.view.append_slash_notfound_view` -as the Not Found view, :app:`Pyramid` still must generate a ``404 Not Found`` -response when it cannot redirect to a slash-appended URL; this not found -response will be visible to site users. + @view_config(route_name='noslash') + def no_slash(request): + return Response('No slash') -If you don't care what this 404 response looks like, and only you need -redirections to slash-appended route URLs, you may use the -:func:`~pyramid.view.append_slash_notfound_view` object as the Not Found view -as described above. However, if you wish to use a *custom* notfound view -callable when a URL cannot be redirected to a slash-appended URL, you may -wish to use an instance of the -:class:`~pyramid.view.AppendSlashNotFoundViewFactory` class as the Not Found -view, supplying a :term:`view callable` to be used as the custom notfound -view as the first argument to its constructor. For instance: + @view_config(route_name='hasslash') + def has_slash(request): + return Response('Has slash') -.. code-block:: python - :linenos: - - from pyramid.httpexceptions import HTTPNotFound - from pyramid.view import AppendSlashNotFoundViewFactory + def main(g, **settings): + config = Configurator() + config.add_route('noslash', 'no_slash') + config.add_route('hasslash', 'has_slash/') + config.scan() - def notfound_view(context, request): - return HTTPNotFound('It aint there, stop trying!') +.. warning:: - custom_append_slash = AppendSlashNotFoundViewFactory(notfound_view) - config.add_view(custom_append_slash, context=HTTPNotFound) + You **should not** rely on this mechanism to redirect ``POST`` requests. + The redirect of the slash-appending not found view will turn a ``POST`` + request into a ``GET``, losing any ``POST`` data in the original + request. -The ``notfound_view`` supplied must adhere to the two-argument view callable -calling convention of ``(context, request)`` (``context`` will be the -exception object). +See :ref:`view_module` and :ref:`changing_the_notfound_view` for for a more +general description of how to configure a view and/or a not found view. .. index:: pair: debugging; route matching |
