Reputation: 121
I'm trying to create an app, say activitylogapp in the project that detects if in another app say Employeeapp some models are changed/updated and keep a log. I don't want touch Employeeapp. I can access changes by using signals in the models.py of activitylodapp. By this:
from django.db.models.signals import post_save
from anotherapp.models import Employee
from django.dispatch import receiver
@receiver(post_save, sender=Employee)
def save_handler(sender, instance, created, **kswargs):
"Things I want to do"
The problem is I also want to access which user made these changes, like request.user.username that is used in views.py. Is it possible without explicitly injecting request object from view to activitylog app?
Upvotes: 0
Views: 61
Reputation: 2335
You can add a primitive middleware into your "activitylogapp" with process_request
to store the request
.
As for storing the request
, I see 2 options:
Ugly but fast to implement. Save the request
globally. It shouldn't affect anything as you get a fresh new cloned thread for each request, which dies right after the request has been processed.
More sophisticated, without globals. Utilize the fact, that Django signals create weak references to their receiver functions. So you can attach save_handler
to the request
itself, and they will get GC-ed together in the end. Something like that:
class MyMiddleware(object):
def process_request(request):
def save_handler(sender, instance, created, **kswargs):
user = request.user
"do the stuff you want to do"
# without the following line, the save_handler will be
# garbage collected right away since nothing references it
request._my_save_handler_instance = save_handler
post_save.register(save_handler, ...)
Upvotes: 1