具有多表继承的父类的Django post_save信号

时间:2013-02-07 18:22:44

标签: django django-models multi-table-inheritance

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

借用示例from another question

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 个答案:

答案 0 :(得分:12)

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)

度过愉快的一天!

答案 1 :(得分:3)

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

答案 2 :(得分:1)

我设法使继承的信号接收器与@receiver装饰器一起使用。 See relevant Django documentation

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 Mandrekarhis answer

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)

答案 3 :(得分:0)

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