Question

I have a class method (outside of a view) who needs the logged user's information. How can i retrieve the logged in user without passing the request to the method? Unfortunately i can't find nowhere a nice solution and it's not logical just not exist such a way to do it, because Django should store somewhere the logged in user. Otherwise (i believe) it would be impossible to use @login_required decorator from django.contrib.auth.decorators. Right?

So if it's not possible why it's not? Why Django works like this if the only think i want is the logged in user and not all the informations inside request?

Thanks in advance.

Was it helpful?

Solution

About decorators, it is wrong. Actually decorators called with request argument.

I believe better way is that passing user or request object to class's method. But there are other ways to access request.

Here is the code that we use. You need to add this middleware to MIDDLEWARES. And import & calling get_request function.

Update July 2017: Tested with Python 3.6.1 and Django 1.10.7, based in the original code from this answer and in the Writing your own middleware documentation.

  • First create a new app, ie. startapp request_middleware.
  • Then add "request_middleware" to your INSTALLED_APPS in settings.py.
  • After that paste the code bellow in, ie. request_middleware.middleware.py.
  • Finally add "request_middleware.middleware.RequestMiddleware" to your MIDDLEWARE in settings.py (In my case I've placed it in between 'debug_toolbar.middleware.DebugToolbarMiddleware' and 'django.middleware.security.SecurityMiddleware' as far above the list as I could).

# request_middleware.middleware.py

from threading import current_thread

_REQUESTS = {}


class RequestNotFound(Exception):
    def __init__(self, message):
        self.message = message


def get_request():
    thread = current_thread()
    if thread not in _REQUESTS:
        raise RequestNotFound('global request error')
    else:
        return _REQUESTS[thread]


class RequestMiddleware(object):
    def __init__(self, get_response):
        self.get_response = get_response

    def process_request(self, request):
        _REQUESTS[current_thread()] = request

    def __call__(self, request):
        self.process_request(request)
        response = self.get_response(request)

        return response

After that simply do from request_middleware.middleware import get_request in order to use get_request in your code.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top