Я просто использую сайт admin в Django. У меня есть 2 сигнала Django (pre_save и post_save). Я хотел бы иметь имя пользователя текущего пользователя. Как мне это сделать? Кажется, я не могу отправить запрос, или я этого не понял.
Спасибо
Я просто использую сайт admin в Django. У меня есть 2 сигнала Django (pre_save и post_save). Я хотел бы иметь имя пользователя текущего пользователя. Как мне это сделать? Кажется, я не могу отправить запрос, или я этого не понял.
Спасибо
если вы используете сайт администратора, почему бы не использовать кукурузную модель admin
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 )
сигнал - это то, что запускается каждый раз, когда объект сохраняется независимо от того, выполняется ли это администратором или каким-либо процессом, который не привязан к запросу, и на самом деле не является подходящим местом для выполнения запроса действия
Не желая вмешиваться в нить-локальное состояние, я решил попробовать другой подход. Насколько я могу судить, обработчики сигналов 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.
В обоих сигналах сигнал посылает три аргумента,
Вам нужно, чтобы Момент был изменен...
def signal_catcher(sender, instance, **kwargs):
uname = instance.username
Вы можете использовать промежуточное программное обеспечение для хранения текущего пользователя: http://djangosnippets.org/snippets/2179/
Затем вы сможете получить пользователя с get_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, и вставьте промежуточное программное обеспечение после "django.contrib.auth.middleware.AuthenticationMiddleware" в settings.py
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