6

在 Django 中,如果您有使用多表继承的模型,并且您为父类上的 post_save 信号定义了接收器,那么在保存子类的实例时是否会调用该接收器函数?

借用另一个问题的例子:

class Animal(models.Model):
    category = models.CharField(max_length=20)

class Dog(Animal):
    color = models.CharField(max_length=10)

def echo_category(sender, **kwargs):
    print "category: '%s'" % kwargs['instance'].category

post_save.connect(echo_category, sender=Animal)

如果我做:

>>> dog = Dog.objects.get(...)
>>> dog.category = "canine"
>>> dog.save()

echo_category调用接收函数吗?

4

4 回答 4

15
post_save.connect(my_handler, ParentClass)
# connect all subclasses of base content item too
for subclass in ParentClass.__subclasses__():
    post_save.connect(my_handler, subclass)

祝你今天过得愉快!

于 2014-07-08T06:13:25.187 回答
3

查看: https ://code.djangoproject.com/ticket/9318 似乎大多数将信号传播到子类中的超级。

于 2013-02-07T18:44:51.300 回答
1

不,它不会被调用。请参阅Django 跟踪中的#9318

于 2013-02-07T18:44:25.373 回答
1

我设法让继承的信号接收器与@receiver装饰器一起工作。查看相关的 Django 文档

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

class Animal(models.Model):
    category = models.CharField(max_length=20)

    @receiver(post_save)
    def echo_category(sender, **kwargs):
        print ("category: '%s'" % kwargs['instance'].category)

class Dog(Animal):
    color = models.CharField(max_length=10)

此解决方案在Python 3.6.8 Django 2.2中有效

当我这样做时

>>> from myapp.models import Dog
>>> dog = Dog()
>>> dog.category = "canine"
>>> dog.save()
category: 'canine'
>>>

没问题。一切似乎都在外壳上工作。


有点不相关,但是当我通过管理面板编辑模型时,它被调用了两次,所以我通过检查'created'kwarg 来过滤它们。在一个调用中它是假的,另一个是真的,所以我只是放入了一个简单的 if 块。该解决方法的功劳归功于 Pratik Mandrekar他的回答

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

class Animal(models.Model):
    category = models.CharField(max_length=20)

    @receiver(post_save)
    def echo_category(sender, **kwargs):
        if not kwargs.get('created'):
            print ("category: '%s'" % kwargs['instance'].category)

class Dog(Animal):
    color = models.CharField(max_length=10)
于 2019-05-25T19:37:09.897 回答