I have a few model inheritance levels in Django:
class WorkAttachment(models.Model): """ Abstract class that holds all fields that are required in each attachment """ work = models.ForeignKey(Work) added = models.DateTimeField(default=datetime.datetime.now) views = models.IntegerField(default=0) class Meta: abstract = True class WorkAttachmentFileBased(WorkAttachment): """ Another base class, but for file based attachments """ description = models.CharField(max_length=500, blank=True) size = models.IntegerField(verbose_name=_('size in bytes')) class Meta: abstract = True class WorkAttachmentPicture(WorkAttachmentFileBased): """ Picture attached to work """ image = models.ImageField(upload_to='works/images', width_field='width', height_field='height') width = models.IntegerField() height = models.IntegerField()
There are many different models inherited from WorkAttachmentFileBased
and WorkAttachment
. I want to create a signal, which would update an attachment_count
field for parent work, when attachment is created. It would be logical, to think that signal made for parent sender (WorkAttachment
) would run for all inherited models too, but it does not. Here is my code:
@receiver(post_save, sender=WorkAttachment, dispatch_uid="att_post_save") def update_attachment_count_on_save(sender, instance, **kwargs): """ Update file count for work when attachment was saved.""" instance.work.attachment_count += 1 instance.work.save()
Is there a way to make this signal work for all models inherited from WorkAttachment
?
Python 2.7, Django 1.4 pre-alpha
P.S. I've tried one of the solutions I found on the net, but it did not work for me.
Models inheritance works the same way as normal Python class inheritance works, the only difference is, whether we want the parent models to have their own table in the database or not.
Django includes a “signal dispatcher” which helps decoupled applications get notified when actions occur elsewhere in the framework. In a nutshell, signals allow certain senders to notify a set of receivers that some action has taken place.
Model inheritance in Django works almost identically to the way normal class inheritance works in Python, but the basics at the beginning of the page should still be followed. That means the base class should subclass django. db. models.
Django Signals - post_delete()To notify another part of the application after the delete event of an object happens, you can use the post_delete signal.
You could register the connection handler without sender
specified. And filter the needed models inside it.
from django.db.models.signals import post_save from django.dispatch import receiver @receiver(post_save) def my_handler(sender, **kwargs): # Returns false if 'sender' is NOT a subclass of AbstractModel if not issubclass(sender, AbstractModel): return ...
Ref: https://groups.google.com/d/msg/django-users/E_u9pHIkiI0/YgzA1p8XaSMJ
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With