在post_save信号中访问用户请求
我在我的项目中做了一个叫做 post_save 的信号。
from django.db.models.signals import post_save
from django.contrib.auth.models import User
# CORE - SIGNALS
# Core Signals will operate based on post
def after_save_handler_attr_audit_obj(sender, **kwargs):
print User.get_profile()
if hasattr(kwargs['instance'], 'audit_obj'):
if kwargs['created']:
kwargs['instance'].audit_obj.create(operation="INSERT", operation_by=**USER.ID**).save()
else:
kwargs['instance'].audit_obj.create(operation="UPDATE").save()
# Connect the handler with the post save signal - Django 1.2
post_save.connect(after_save_handler_attr_audit_obj, dispatch_uid="core.models.audit.new")
在 operation_by 这一列中,我想获取用户的 ID 并把它存起来。有没有什么办法可以做到这一点?
13 个回答
10
我通过查看堆栈来找到视图,然后查看这个视图的局部变量,以获取请求信息。虽然这有点像是变通的方法,但确实有效。
import inspect, os
@receiver(post_save, sender=MyModel)
def get_user_in_signal(sender, **kwargs):
for entry in reversed(inspect.stack()):
if os.path.dirname(__file__) + '/views.py' == entry[1]:
try:
user = entry[0].f_locals['request'].user
except:
user = None
break
if user:
# do stuff with the user variable
13
你可以通过中间件来实现这个功能。首先,在你的应用里创建一个叫 get_request.py
的文件。然后
from threading import current_thread
from django.utils.deprecation import MiddlewareMixin
_requests = {}
def current_request():
return _requests.get(current_thread().ident, None)
class RequestMiddleware(MiddlewareMixin):
def process_request(self, request):
_requests[current_thread().ident] = request
def process_response(self, request, response):
# when response is ready, request should be flushed
_requests.pop(current_thread().ident, None)
return response
def process_exception(self, request, exception):
# if an exception has happened, request should be flushed too
_requests.pop(current_thread().ident, None)
接下来,把这个中间件添加到你的设置里:
MIDDLEWARE = [
....
'<your_app>.get_request.RequestMiddleware',
]
然后在你的信号中添加导入:
from django.db.models.signals import post_save
from django.contrib.auth.models import User
from <your_app>.get_request import current_request
# CORE - SIGNALS
# Core Signals will operate based on post
def after_save_handler_attr_audit_obj(sender, **kwargs):
print(Current User, current_request().user)
print User.get_profile()
if hasattr(kwargs['instance'], 'audit_obj'):
if kwargs['created']:
kwargs['instance'].audit_obj.create(operation="INSERT", operation_by=**USER.ID**).save()
else:
kwargs['instance'].audit_obj.create(operation="UPDATE").save()
# Connect the handler with the post save signal - Django 1.2
post_save.connect(after_save_handler_attr_audit_obj, dispatch_uid="core.models.audit.new")
41
这件事做不了。因为当前用户的信息只能通过请求来获取,而在单纯使用模型功能的时候,这个请求是无法得到的。你需要在视图中以某种方式来访问用户的信息。