Django 4.2:“receiver”装饰器未接收信号

myss37ts  于 2023-06-25  发布在  Go
关注(0)|答案(1)|浏览(154)

我正在尝试Django信号。
在文档中,有两种方法可以将接收器连接到信号。
1.使用Signal.connect方法
1.使用receiver装饰器
以下是我实现的:

# models.py
from django.db import models
from django.dispatch import receiver

from .signals import demo_signal

class Demo(models.Model):
    demo = models.CharField("demo", max_length=50)

    def send_signal(self):
        demo_signal.send(self)
        print('signal sent')

    def connect_receiver(self):
        demo_signal.connect(signal_handler, sender=self)

@receiver(demo_signal, sender=Demo)
def signal_handler(**kwargs):
    print('signal handled')
# signals.py
from django.dispatch import Signal

demo_signal = Signal()

但是,当我调用send_signal方法时,除非我先调用connect_receiver方法,否则不会打印出signal handled

In [1]: demo = Demo.objects.get(pk=2)

In [2]: demo
Out[2]: <Demo: Demo object (2)>

In [3]: demo.send_signal()
signal sent

In [4]:

有趣的是,在如下实现pre_delete_handler之后,在没有连接的情况下,调用delete方法确实调用了pre_delete_handler

@receiver(pre_delete, sender=Demo)
def pre_delete_handler(instance, **kwargs):
    print(instance, kwargs)
    print('pre delete')

接收器确实接收到没有sender参数的信号:

@receiver(pre_delete)
def pre_delete_handler(instance, **kwargs):
    print(instance, kwargs)
    print('pre delete')

但是我如何让它听特定的模型?为什么在我的情况下发送信号不调用它的接收器(装饰signal_handler)?

u59ebvdq

u59ebvdq1#

哇...在发布这个问题后不久,我就知道为什么了。
所以,如果我想调用模型特定的接收器,我必须传递一个类而不是一个示例。即self.__class__

class Demo(models.Model):
    demo = models.CharField("demo", max_length=50)

    def send_signal(self):
        demo_signal.send(sender=self.__class__)
        print('signal sent')

@receiver(demo_signal, sender=Demo)
def signal_handler(**kwargs):
    print('demo signal handled')

相关问题