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

问题描述 投票:2回答:2

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

python django django-signals
2个回答
1
投票

为什么要将信号作为实例方法?似乎没有任何理由。你只需要确保当你编写信号函数本身时,它会传递相关的实例 - 例如作为instance kwarg - 正如内置的pre-savepost-save信号那样。

编辑后添加到问题但这正是信号应该如何工作。有一个信号功能,它发送信号以及任何关联信息,以及任何数量的收听信号的接收器。但是接收器本身并不与特定实例相关联 - 它们不能,实例仅在您实际实例化它时存在(!),否则它只是数据库中的一行。

也许您的接收器功能可以查询相关对象本身,并在那里更新它们 - 甚至更好,做一个update查询来就地更改它们。


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
© www.soinside.com 2019 - 2024. All rights reserved.