Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use Django model inheritance with signals?

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.

like image 458
Silver Light Avatar asked Oct 17 '11 10:10

Silver Light


People also ask

Can we inherit model in Django?

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.

What is Django DB models signals?

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.

What are the model inheritance style in Django?

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.

What is the use of the Post_delete signal in Django?

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.


1 Answers

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

like image 89
rwanyoike Avatar answered Sep 21 '22 04:09

rwanyoike