Django信号接收器接受自我论证

时间:2011-12-18 18:51:30

标签: python django django-signals

我正在制作游戏。每当某个动作发生时,它就会发出一个信号。信号被许多不同的物体使用。例如,玩家模型实例将重新产生一点点健康,灯笼将减少他们留下的油。我想要这些模型的实例在发出信号时做出反应并修改它们的数据。但是,我不知道如何在接收函数中引用实例本身,因为我不能将“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通知感兴趣的对象(即使用接收方法)发生事件,因此它们可以触发它们自己的特定行为。

2 个答案:

答案 0 :(得分:1)

为什么要将信号作为实例方法?似乎没有任何理由。您只需确保在编写信号函数本身时,它会传递相关实例 - 例如instance kwarg - 与内置pre-savepost-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