- August 30, 2010
- middleware user request local thread
- -1 (after 5 ratings)
Mechanism to obtain a
request.user object without the
request object itself. Requires
MIDDLEWARE_CLASSES settings variable.
Important: works under assumption that within a web server each request is handled by a separate thread (as for example in the Apache HTTP server).
Dev note: works fine with one-threaded Django's development server, each request resets current user; no worries 'bout many media requests - they won't (at least shouldn't) be using Django on the production server.
Ref: originally found in the gatekeeper app.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
from django.conf import settings USER_ATTR_NAME = getattr(settings, 'LOCAL_USER_ATTR_NAME', '_current_user') try: from threading import local except ImportError: from django.utils._threading_local import local _thread_locals = local() from new import instancemethod def _do_set_current_user(user_fun): setattr(_thread_locals, USER_ATTR_NAME, instancemethod(user_fun, _thread_locals, type(_thread_locals))) def _set_current_user(user=None): ''' Sets current user in local thread. Can be used as a hook e.g. for shell jobs (when request object is not available). ''' _do_set_current_user(lambda self: user) class LocalUserMiddleware(object): def process_request(self, request): # request.user closure; asserts laziness; memoization is implemented in # request.user (non-data descriptor) _do_set_current_user(lambda self: getattr(request, 'user', None)) def get_current_user(): current_user = getattr(_thread_locals, USER_ATTR_NAME, None) return current_user() if current_user else current_user