Можно ли выборочно подавить сигнал post_save (или другой) в Django? - PullRequest
6 голосов
/ 27 января 2011

Мне интересно, возможно ли выборочно подавить сигнал Django (например, post_save или post_init) при создании объекта или, альтернативно, отправить ему определенные параметры.

То, что у меня есть, это User объект, который можно создавать различными способами и в разных местах моего кода. Поэтому, чтобы автоматически назначать пользовательский объект Profile каждому User, я использую сигнал post_save. Однако в одном конкретном случае есть дополнительная информация, которую я хочу привязать к созданному объекту Profile. Передача его в качестве аргументов сигналу post_save была бы полезной, но это не представляется возможным.

Другой вариант - создать объект Profile вручную, но мне нужно сделать это после сохранения User, иначе Profile не может быть привязан к экземпляру User. Однако сохранение экземпляра User приводит к созданию другого Profile с помощью функции, вызываемой сигналом.

И я не могу просто получить только что созданный объект Profile, так как это приводит к ошибке 'Profile' object is unsubscriptable. Любой совет?

Обновление:

Вот пример возможной ситуации:

def createUserProfile(sender, instance, created, **kwargs):
if created:  
    profile, created = Profile.objects.get_or_create(user=instance)
    if extra_param:
        profile.extra_param = extra_param
    profile.save()

post_save.connect(createUserProfile, sender=User)

def signup(request):
   ...
   extra_param = 'param'
   user.save()

Как получить переменную extra_param в методе signup в метод createUserProfile, где она должна храниться как часть объекта Profile?

Ответы [ 2 ]

2 голосов
/ 28 января 2011

Почему это не работает для вас?

user = User(...)
user.save()
# profile has been created transparently by post_save event
profile = user.profile
profile.extra_stuff = '...'
profile.save()

Если вы одержимы параметрами, передающими событие, возможно, но зло:

user = User()
user._evil_extra_args = { ... }
user.save()

In event:
extra_args = getattr(user, '_evil_extra_args', False)

Это зло, потому что люди, которые будут читать ваш код, не будут знать, какого черта эти _evil_extra_args и как это работает.

0 голосов
/ 27 января 2011

Задержка post_save невозможна (если вы не хотите полностью отключить ее ), но и в этом нет необходимости. Передача параметра в профиль не является проблемой:

class UserProfile(models.Model):  
    user = models.ForeignKey(User)
    other = models.SomeField()

def create_user_profile(sender, instance, created, other_param=None, **kwargs):  
    if created:  
       profile, created = UserProfile.objects.get_or_create(user=instance)
       profile.other(other_param) # or whatever
       profile.save()

post_save.connect(create_user_profile, sender=User, other_param=p)
...