Приемник сигнала Джанго принимает собственный аргумент - PullRequest
2 голосов
/ 18 декабря 2011

Я создаю игру.Каждый раз, когда происходит определенное действие, он посылает сигнал.Сигнал используется многими различными объектами.Например, экземпляры модели игрока будут восстанавливать немного здоровья, фонари уменьшат оставшееся масло.Я хочу, чтобы экземпляры этой модели реагировали и модифицировали свои данные при излучении сигнала.Тем не менее, я не знаю, как ссылаться на сам экземпляр в функции приемника, так как я не могу поместить «self» в список аргументов, которые использует функция.

class Lantern(models.Model):
    oil_left= models.IntegerField(default=4)

    @receiver(mySignal)
    def burn(sender, **kwargs):
        self.oil_left  -= 1 #<- self is not defined obviously
        self.save() #<- self is not defined obviously

Почему получатель какметод экземпляра?Потому что список экземпляров, реагирующих на сигнал, неизвестен при отправке сигнала.Сигнал - это просто пинг, уведомляющий заинтересованные объекты (т. Е. С помощью метода получателя) о том, что произошло событие, чтобы они могли инициировать свое собственное специфическое поведение.

Ответы [ 2 ]

1 голос
/ 18 декабря 2011

Почему вы хотите, чтобы сигнал был методом экземпляра?Кажется, нет никаких причин для этого.Вам просто нужно убедиться, что при написании самой функции сигнала она передает соответствующий экземпляр - например, как instance kwarg - точно так же, как это делают встроенные сигналы pre-save и post-save.

Добавлено после редактирования в вопрос Но именно так и должны работать сигналы.Существует одна функция сигнала, которая отправляет сигнал вместе с любой информацией об ассоциации и любым количеством приемников, которые прослушивают сигнал.Но сами получатели не связаны с конкретными экземплярами - они не могут быть, экземпляр существует только тогда, когда вы на самом деле создаете его (!), А в противном случае это просто строка в базе данных.

Возможно, ваша функция получателямог бы запросить соответствующие объекты сам и обновить их там - или, что еще лучше, сделать запрос update, чтобы изменить их на месте.

0 голосов
/ 20 декабря 2018

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

from django.db.models.signals import post_save
from django.dispatch import receiver

@receiver(post_save, sender=YourModel)
def your_action_call(sender, instance, **kwargs):
   pass
   #some logic
...