我只是在Django中使用管理站点。我有两个Django信号(pre_save和post_save)。我想获得当前用户的用户名。我该怎么做?似乎我不能发送请求,或者我没有理解它。
谢谢
我只是在Django中使用管理站点。我有两个Django信号(pre_save和post_save)。我想获得当前用户的用户名。我该怎么做?似乎我不能发送请求,或者我没有理解它。
谢谢
我不想去处理线程本地状态,所以决定尝试另一种方法。据我所知,post_save
和pre_save
信号处理程序在调用save()
的线程中同步调用。如果我们处于正常的请求处理循环中,则可以沿着堆栈向上查找请求对象作为某个本地变量。例如:
from django.db.models.signals import pre_save
from django.dispatch import receiver
@receiver(pre_save)
def my_callback(sender, **kwargs):
import inspect
for frame_record in inspect.stack():
if frame_record[3]=='get_response':
request = frame_record[0].f_locals['request']
break
else:
request = None
...
如果有当前请求,您可以从中获取user
属性。
注意:正如inspect
模块文档中所说,
该函数依赖于解释器中的Python堆栈帧支持,在所有Python实现中都不一定存在。
如果您正在使用管理员网站,为什么不使用自定义模型管理呢?
class MyModelAdmin( admin.ModelAdmin ):
def save_model( self, request, obj, form, change ):
#pre save stuff here
obj.save()
#post save stuff here
admin.site.register( MyModel, MyModelAdmin )
信号是每次对象保存时都会触发的事件,无论是由管理员还是一些与请求无关且不适合用于执行基于请求的操作的进程进行保存。
m2m
关系的更改。 - Benget_current_user()
来获取用户。class Singleton(type):
'''
Singleton pattern requires for GetUser class
'''
def __init__(cls, name, bases, dicts):
cls.instance = None
def __call__(cls, *args, **kwargs):
if cls.instance is None:
cls.instance = super(Singleton, cls).__call__(*args, **kwargs)
return cls.instance
class NotLoggedInUserException(Exception):
'''
'''
def __init__(self, val='No users have been logged in'):
self.val = val
super(NotLoggedInUser, self).__init__()
def __str__(self):
return self.val
class LoggedInUser(object):
__metaclass__ = Singleton
user = None
def set_user(self, request):
if request.user.is_authenticated():
self.user = request.user
@property
def current_user(self):
'''
Return current user or raise Exception
'''
if self.user is None:
raise NotLoggedInUserException()
return self.user
@property
def have_user(self):
return not user is None
创建自己的中间件类,将用户设置为LoggedInUser实例,并在settings.py中在'django.contrib.auth.middleware.AuthenticationMiddleware'之后插入我们的中间件。
from useranytimeaccess import LoggedInUser
class LoggedInUserMiddleware(object):
'''
Insert this middleware after django.contrib.auth.middleware.AuthenticationMiddleware
'''
def process_request(self, request):
'''
Returned None for continue request
'''
logged_in_user = LoggedInUser()
logged_in_user.set_user(request)
return None
在信号中导入LoggedInUser类并获取当前用户
logged_in = LoggedInUser()
user = logged_in.user
@receiver(post_save, sender=FlowList)
def flow_list_post_save(sender, instance, created, **kwargs):
import inspect
request = None
try:
request = next((frame[0].f_locals['request'] for frame in inspect.stack() if frame[3] == 'get_response'), None)
except StopIteration:
pass
在这两个信号中,信号都发送了三个参数:
你需要的是被修改的实例...
def signal_catcher(sender, instance, **kwargs):
uname = instance.username
sender
(发送信号的类)始终排在第一位。 - Daniel Roseman