Check out: https://code.djangoproject.com/ticket/9318 It appears that most propagate the signal to the super in the subclass.
Django post_save signal on parent class with multi-table inheritance
-
07-03-2022 - |
Question
In Django, if you have models that use multi-table inheritance, and you define a receiver for a post_save signal on the parent class, does that receiver function get called when an instance of the child class is saved?
Borrowing an example 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)
If I do:
>>> dog = Dog.objects.get(...)
>>> dog.category = "canine"
>>> dog.save()
Will the echo_category
receiver function be called?
Solution 2
OTHER TIPS
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!
No, it will not be called. See #9318 in Django trac.
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)