Пользовательская модель Django 1.5 - ограничение сигналов

Это написано в документе, который :

Еще одно ограничение пользовательских моделей User заключается в том, что вы не можете использовать django.contrib.auth.get_user_model () в качестве отправителя или цели обработчика сигналов. Вместо этого вы должны зарегистрировать обработчик с полученной моделью User. См. «Сигналы» для получения дополнительной информации о регистрации отправляющих сигналов.

Думаю, это означает, что вы можете делать следующее:

from django.contrib.auth import get_user_model

User = get_user_model()

@receiver(post_save, sender=User)
def user_saved(sender=None, instance=None, **kwargs):
    # something

Не так ли? Мне просто интересно, хорошо ли я понимаю (не понимаю, почему говорят, что это «ограничение», но все равно, просто хочу проверить).


person lajarre    schedule 25.04.2013    source источник


Ответы (3)


Это должно сработать. Я думаю, они хотят использовать ту же функцию, что и отправитель

в документе:

как отправитель или цель обработчика сигнала. Вместо этого необходимо зарегистрировать обработчик с полученной моделью пользователя.

person juanpex    schedule 26.04.2013

Это связано с тем, что объект не был «установлен» при создании сигнала, поэтому get_user_model () не может найти объект, к которому он должен присоединить обработчик сигнала.

См. эту ошибку для получения подробной информации о том, как она была обнаружена и в чем проблема.

Ваш пример не будет работать, потому что вызов get_user_model() завершится ошибкой по этой причине. На данный момент единственный способ заставить обработчик сигналов работать с пользовательским классом User - это дать ему имя напрямую без использования get_user_model(), например

@receiver(post_save, sender=myapp.MyUserModel) # can't use get_user_model() here
def user_saved(sender=None, instance=None, **kwargs):
    # something

Ваш стиль кодирования также может потребовать некоторой работы: когда вы запускаете User = get_user_model(), он создает переменную с именем User со значением, установленным в результате вызова функции get_user_model(). Соглашение Python (и большинство других языков) заключается в том, что обычные переменные начинаются с буквы нижнего регистра, а классы - с буквы верхнего регистра.

Таким образом, user = get_user_model(), а затем использование переменной user будет иметь больше смысла для любого, кто читает ваш код, и поможет избежать путаницы в будущем.

person Brendan Quinn    schedule 14.05.2013
comment
Не уверен, что вы имеете в виду, говоря о строчных буквах, User в этом случае вызывается или является классом, как вы это называете. Кроме того, ваша точка зрения верна при использовании get_user_model в том же файле models.py, что и AUTH_USER_MODEL. Это хороший аргумент, но ваше сообщение непонятно - person lajarre; 14.05.2013

Вы можете просто использовать параметр AUTH_USER_MODEL или любую модель в виде строки, например 'users.MyCustomUser':

def user_post_save_handler(**kwargs):
    # do something
post_save.connect(user_post_save_handler, sender=settings.AUTH_USER_MODEL)
person Tobias Lorenz    schedule 06.07.2015