我正在制作游戏。每当某个动作发生时,它就会发出一个信号。信号被许多不同的物体使用。例如,玩家模型实例将重新产生一点点健康,灯笼将减少他们留下的油。我想要这些模型的实例在发出信号时做出反应并修改它们的数据。但是,我不知道如何在接收函数中引用实例本身,因为我不能将“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
为什么接收器作为实例方法?因为在发送信号时,对信号作出反应的实例列表是未知的。该信号仅仅是一个ping通知感兴趣的对象(即使用接收方法)发生事件,因此它们可以触发它们自己的特定行为。
答案 0 :(得分:1)
为什么要将信号作为实例方法?似乎没有任何理由。您只需确保在编写信号函数本身时,它会传递相关实例 - 例如instance
kwarg - 与内置pre-save
和post-save
信号完全相同。
编辑后添加问题但这正是信号应该如何工作的原因。有一个信号功能,它发送信号以及任何关联信息,以及任何数量的收听信号的接收器。但是接收器本身并不与特定实例相关联 - 它们不能,实例仅在您实际实例化它时存在(!),否则它只是数据库中的一行。
也许您的接收器功能可以查询相关对象本身,并在那里更新它们 - 甚至更好,执行update
查询以就地更改它们。
答案 1 :(得分:0)
信号与模型对象类的更改无关,而是每次在与模型关联的表中写入数据库之后/之前都要做的一些事情
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