Получить текущий логин пользователя сигнал в Джанго - PullRequest
11 голосов
/ 18 января 2011

Я просто использую админ-сайт в Django. У меня есть 2 сигнала Django (pre_save и post_save). Я хотел бы иметь имя пользователя текущего пользователя. Как бы я это сделал? Кажется, я не могу отправить запрос или я не понял этого.

Спасибо

Ответы [ 5 ]

19 голосов
/ 16 января 2012

Неохотно возиться с локальным состоянием потока, я решил попробовать другой подход. Насколько я могу судить, обработчики сигналов 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.

10 голосов
/ 16 ноября 2011

Если вы используете сайт администратора, почему бы не использовать пользовательскую модель 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 )

Сигнал - это то, что запускается каждый раз, когда объект сохраняется, независимо от того, выполняется ли это администратором или каким-либо процессом, который не привязан к запросу и не является подходящим местом для выполнения запроса на основе действия

1 голос
/ 13 февраля 2011

Вы можете использовать промежуточное ПО для хранения текущего пользователя: http://djangosnippets.org/snippets/2179/

Тогда вы сможете получить пользователя с get_current_user()

0 голосов
/ 19 сентября 2011

Мы можем решить эту проблему, используя промежуточные классы.Создайте одноэлементный класс, в котором будет храниться пользовательская переменная.

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
0 голосов
/ 18 января 2011

В обоих сигналах сигнал посылает три аргумента,

  • Отправитель
  • Instance
  • Использование

То, что вам нужно, - это изменяемое Мгновенное ...

def signal_catcher(sender, instance, **kwargs):
    uname = instance.username

http://docs.djangoproject.com/en/dev/ref/signals/#pre-save

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...