3

I am using Django 1.8 and I am trying to implement a simple logging to a model. I have overridden the save method of the class. However, I also want to log which user is responsible for the change but the request object is not available since it's not passed into the save method. I don't want to pass the user in all occurrences of the save method because I am using django-rest-framework.

Here is my code:

def save(self, *args, **kwargs):
    order = super(Order, self).save(*args, **kwargs)
    try:
        json_object = serializers.serialize('json', [ order, ])
        # I want to log the current user too.
        OrderLog.objects.create(order = order, object = json_object)
    except Exception as e:
        print e
    return order
scc
  • 10,342
  • 10
  • 51
  • 65
Utku Turunç
  • 334
  • 1
  • 7

2 Answers2

2

It is possible to get current user. You have to implement your own small middleware for it.

You need following method and middleware class.

Your middleware file

from threading import local

_thread_locals = local()

def get_current_user():
    return getattr(_thread_locals, 'user', None)

class ThreadLocals( object ):
    """Middleware that gets various objects from the request object and saves them in thread local storage."""
    def process_request( self, request ):
    _thread_locals.user = getattr( request, 'user', None )

Settings.py

MIDDLEWARE_CLASSES += (
    "your.path.to.middleware.ThreadLocals"
)

Your save method somewere

save(self):
    from your.path.to.middleware import get_current_user

    user = get_current_user()
-1

There is no way to get the user that did the request in the model's save method, since the model lives on its own.
You can call the save method whereever you like, even if there is no request at all.

Thus you'd need to pass the user to every save invocation or alternatively need to log in the function that calls save, before/after calling save.

Chris Schäpers
  • 1,238
  • 10
  • 17