在django模型中发送和接收信号

问题描述 投票:8回答:3

我使用的是django 2.0.8和Python 3.5。我希望能够在将对象保存到数据库时发送和接收自定义信号。

我已经关注了listening to signalscore signals bundled with Django上的Django文档 - 但是,我无法让我的例子工作。

这是我到目前为止:

的myapp / models.py

from django.db import models
import django.dispatch

my_signal = django.dispatch.Signal(providing_args=["name"])

class Foo(models.Model):
    name = models.CharField(max_length=16)

def save(self, *args, **kwargs):
    try:
        # Call the "real" save() method.
        super().save(*args, **kwargs)  

        # Fire off signal         
        my_signal.send(sender=self.__class__, name=self.name)

    except Exception as e:
        print ('Exception:', e)
        #pass

MYAPP / signals.py

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


@receiver(post_save, sender=Foo)
def foo_handler(sender, **kwargs):
    print('Foo Signal Recieved!')
    print(kwargs)

MYAPP / app.py

class MyappConfig(AppConfig):
name = 'myapp'
label = 'myapp'

def ready(self):
    import myapp.signals

样品用法

from myapp.models import Foo

foo = Foo(name='Homer Simpson')
foo.save() # Object is saved, but event is not fired!

任何人都可以解释为什么信号没有被解雇?

python django django-signals
3个回答
6
投票

看来你需要Django提供的两个功能。 signalcontenttypes

所以先阅读文档

模型Activity与contenttypes相关,似乎你错过了object_id字段,它指示哪个模型实例是crud。

对于每个crud操作,都在创建一个Activity实例。这部分只是用signal.py编写的代码

信号:信号必须连接每个具体模型。幸运的是,请参阅装饰器receiver的源代码。

我们有一个信号列表[post_save,post_delete]和一个模型列表(FoodooChile,FooBarChile)来连接。

在post_save中,创建的参数表示操作是创建或更新。

最后,通常我们在urls.py中导入信号文件,这可能不是最好的做法。


它也与你的settings.py有关。使用'myapp.apps.MyappConfig'替换myapp中的settings.py,或者在default_app_config = 'myapp.apps.MyappConfig'中定义myapp/__init__.py。评论中的上述链接详细描述了这一点


0
投票
  1. myapp.signals你有一个接收器,它接收post_save信号(@receiver(post_save, sender=Foo)),它没有连接到你的信号。
  2. 确保您在应用程序default_app_config = 'myapp.apps.MyappConfig'的__init__.py中使用应用程序配置
  3. 要连接到您创建的信号,请在signals.py文件中尝试: @receiver(my_signal) def my_handler(name, **kwargs): print(name)

0
投票

你正在重新发明轮子,但只能把它放在推车的一侧,可以这么说。

post_save信号总是在保存时发送,因此定义自己的信号是过度的。我知道你有参数,但接收器已经有了sender参数,这是保存的对象,所以你可以做sender.name,你就得到了你需要的值。

除此之外,您有语法错误,您的模型的自定义保存功能不缩进。我不知道这是您的问题中的格式错误,还是它在代码中的样子。无论哪种方式,如果你只是丢弃自定义信号应该工作。

模型

from django.db import models
import django.dispatch


class Foo(models.Model):
    name = models.CharField(max_length=16)

信号

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


@receiver(post_save, sender=Foo)
def foo_handler(sender, **kwargs):
    print(sender.name)

应用

class MyappConfig(AppConfig):
name = 'myapp'
label = 'myapp'

def ready(self):
    import myapp.signals

样品

from myapp.models import Foo

foo = Foo(name='Homer Simpson')
foo.save()
© www.soinside.com 2019 - 2024. All rights reserved.