简体   繁体   中英

Initiate post save on Django abstract parent model, when child model saved

i have this models:

from django.db.models import Model

class SearchModel(Model):  
    class Meta:
        abstract = True

class Book(SearchModel):

    book_id = django_models.BigIntegerField(null=True, blank=True)

    class Meta:
        db_table = 'book'

I need that on book.save() a SearchModel function should be called ( without any code changes on Book/not creating post save signal on Book )

My motivation is that every model inherit from SearchModel, will have some post_save handler (without writing extra code - only inherit Signal)

Is it possible?

That's quite simple: don't provide any specific "sender" when connecting your post_save handler, then in the handler check whether sender is a subclass of SearchModel , ie:

from django.db.signals import post_save
from django.dispatch import receiver
from django.db.models import Model

class SearchModel(Model):  
    class Meta:
        abstract = True

    def on_post_save(self):
        print "%s.on_post_save()" % self

# NB `SearchModel` already inherits from `Model` 
class Book(SearchModel):
    book_id = django_models.BigIntegerField(null=True, blank=True)

    class Meta:
        db_table = 'book'


@receiver(post_save)
def search_on_post_save(sender, instance, **kwargs):
    if issubclass(sender, SearchModel):
         instance.on_post_save()

Then you can provide a default implementation in SearchModel and override it if needed in subclasses.

In your signals.py

from django.db.signals import post_save

def search_on_post_save(sender, instance, **kwargs):
    pass

for subclass in SearchModel.__subclasses__():
    post_save.connect(search_on_post_save, subclass)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM