Django post_save signal on parent class with multi-table inheritance

别来无恙 提交于 2019-12-04 08:41:18

Check out: https://code.djangoproject.com/ticket/9318 It appears that most propagate the signal to the super in the subclass.

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)

have a nice day!

I managed to get inherited signal receivers working with the @receiver decorator. 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)

This solution is valid in Python 3.6.8 Django 2.2

When I do this

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

No problems. Everything seems to work from the shell.


Slightly unrelated, but when I edited models through the admin panel There was an issue with it getting called twice so I filtered them by checking the 'created' kwarg. In one call it was false, the other it was true so I just put in a simple if block. Credit for that workaround goes to Pratik Mandrekar and his 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)

No, it will not be called. See #9318 in Django trac.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!