forked from Pylons/pyramid_cookbook
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
52 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters