Skip to content

Commit

Permalink
add user request attr recipe
Browse files Browse the repository at this point in the history
  • Loading branch information
mcdonc committed Dec 30, 2010
1 parent 5e3a4a0 commit 29f35e8
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 0 deletions.
51 changes: 51 additions & 0 deletions authentication.rst
@@ -0,0 +1,51 @@
Making A "User Object" Available as a Request Attribute
-------------------------------------------------------

This is you: your application wants a "user object". Pyramid is only willing
to supply you with a user *id* (via
``pyramid.security.authenticated_userid``). You're allergic to creating a
simple function that takes a request object and returns a user object from
your domain model for unspecified, dubious reasons.

You've tried using a ``NewRequest`` subscriber to attach a user object to the
request, but the ``NewRequest`` susbcriber is called on every request, even
ones for static resources, and this bothers you (which it should).

Use a combination of a custom request factory and the
``pyramid.configuration.Config.set_request_factory`` method. Here's the
custom request factory:

.. code-block:: python
:linenos:
from pyramid.decorator import reify
from pyramid.request import Request
from pyramid.security import authenticated_userid
class RequestWithUserAttribute(Request):
@reify
def user(self):
# <your database connection, however you get it, the below line
# is just an example>
dbconn = self.registry.settings['dbconn']
userid = authenticated_userid(self)
if userid is not None:
return dbconn['users'].query({'id':userid)})
``pyramid.decorator.reify`` is like the built-in Python ``property``
decorator, but makes sure that "user" turns into a "real" attribute of the
request after the first call rather than a property, which executes over and
over for each access.

Here's how you should use your new request factory in configuration code:

.. code-block:: python
:linenos:
config.set_request_factory(RequestWithUserAttribute)
Then in your view code, you should be able to happily do ``request.user`` to
obtain the "user object" related to that request. It will return ``None`` if
there is no user associated with the request. No inappropriate execution of
``authenticated_userid`` is done (as would be if you used a ``NewRequest``
subscriber).
1 change: 1 addition & 0 deletions index.rst
Expand Up @@ -8,6 +8,7 @@ The Pyramid Cookbook presents topical, practical usages of :mod:`Pyramid`.

static
exceptions
authentication

TODO
----
Expand Down

0 comments on commit 29f35e8

Please sign in to comment.