Reputation: 3680
I wanted to track my models and their CRUD operations through handling post_save, delete and init signals, and then save entry to the Database about this operation handled.
def handle_model_saved(sender, **kwargs):
"""Trap the signal and do whatever is needed"""
entry=CRUD_Storage()
entry.entry='Object \"'+sender._meta.module_name+'\" was saved.'
entry.save()
Then the funny thing, it is a recursion of saves...
I created model CRUD_Storage, i want to prevent it sending signals like pre(post)init, delete, save.
Upvotes: 3
Views: 871
Reputation: 9684
Here is a DRY way of dismissing signals.
If you want to dismiss a signal to avoid recursion, a simple way to go is to set an attribute on the current instance to prevent upcoming signals firing.
This can be done using a simple decorator that checks if the given instance has the 'skip_signal' attribute, and if so prevents the method from being called:
from functools import wraps
def skip_signal():
def _skip_signal(signal_func):
@wraps(signal_func)
def _decorator(sender, instance, **kwargs):
if hasattr(instance, 'skip_signal'):
return None
return signal_func(sender, instance, **kwargs)
return _decorator
return _skip_signal
We can now use it this way:
from django.db.models.signals import post_save
from django.dispatch import receiver
@receiver(post_save, sender=MyModel)
@skip_signal()
def my_model_post_save(sender, instance, **kwargs):
# you processing
pass
m = MyModel()
# Here we flag the instance with 'skip_signal'
# and my_model_post_save won't be called
# thanks to our decorator, avoiding any signal recursion
m.skip_signal = True
m.save()
Hope This helps.
Upvotes: 1
Reputation: 308789
I don't think you can prevent Django from sending those signals.
However, you can adapt your handler to not log saves for your CRUD_Storage
model.
def handle_model_saved(sender, **kwargs):
"""Trap the signal and do whatever is needed"""
if sender == CRUD_Storage:
# return early to prevent recursion of saves
return
entry=CRUD_Storage()
entry.entry='Object \"'+sender._meta.module_name+'\" was saved.'
entry.save()
Upvotes: 3