Skip to content

Instantly share code, notes, and snippets.

@jeanphix
Created November 30, 2011 10:14
Show Gist options
  • Save jeanphix/1408574 to your computer and use it in GitHub Desktop.
Save jeanphix/1408574 to your computer and use it in GitHub Desktop.
Django global user
# middlewares.py
import threading
_thread_locals = threading.local()
def get_current_user():
"""Returns the current user."""
return getattr(_thread_locals, 'user', None)
class GlobalUserMiddleware(object):
"""Puts the current user in thread_locals."""
def process_request(self, request):
_thread_locals.user = getattr(request, 'user', None)
# models.py
from middlewares import get_current_user
MyClass(models.Model):
created_by = models.ForeignKey(User, null=True, blank=True,
default=lambda: get_current_user())
@n1k0
Copy link

n1k0 commented Nov 30, 2011

Bad bad design imho. You should rather pass the current user from a view, eg. (pseudocode):

def my_view(request):
    MyClass.objects.create(foo="bar", created_by=request.user).save()

@jeanphix
Copy link
Author

I agree with you but works fine with admin as well.

It's not a bad pattern but a non "django compliant" one, for exemple flask puts many things in thread_locals (request...) and provides helpers to get back those objects, e.g.:

"import request" gets back current request from anywhere (usefull I think), also raise an exception if not in request context.

@n1k0
Copy link

n1k0 commented Nov 30, 2011

Yeah I know and that's especially what I dislike the most in Flask. I don't like ghost-globals, they're error prone, hard to make scale and hard to mock/test.

@thoas
Copy link

thoas commented Nov 30, 2011

Agreed with @n1k0, it's dangerous and a bad decision especially for your unittests.
It's not the goal of your model to retrieve its data, you should pass data instead.
Global variables is a nasty trick and I had an hard time to remove it in an old application.

Just for the info, what is the use case that requires this trick for your application?

@jeanphix
Copy link
Author

@thoas The need here is just to log which user created or updated the object (for many models) in both frontend and admin...

You both are right, I have no time for that (/budget) but I think I'll move to more qualitative things...

@thoas
Copy link

thoas commented Nov 30, 2011

Hum ok... I see.

Mozilla uses this trick too, to do the same thing for its commonware logger.

Good luck.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment