I'm trying to make Django not to send signal in one case. When adding a new instance of model Delivery
(right after creating a Job
) as an attribute of model Job
, I don't want to send signal because the signal should alert admin that Job
has been edited.
Unfortunately I can't make it work.
@receiver(post_save,sender=Job) # When Job is created or edited
def alert_admin(sender,instance,created,**kwargs):
if created:
email.AdminNotifications.new_order(instance)
else:
email.AdminNotifications.edited_order(instance)
@receiver(post_save,sender=Job) # When job is created, I want to create a delivery object as an attribute of Job
def create_delivery(sender,instance,created,**kwargs):
if created:
delivery,created_delivery = Delivery.objects.get_or_create(job=instance)
instance.delivery = delivery
delivery.save()
post_save.disconnect(alert_admin)
instance.save() # I DONT WANT TO SEND SIGNAL IN THIS CASE
post_save.connect(alert_admin)
Where is the problem? I did this but I still recieve two alerts - New Order
and Edited Order
.
The problem is that you are listening to the same signal twice.
@receiver(post_save,sender=Job) # When Job is created or edited
def alert_admin(sender,instance,created,**kwargs):
###
@receiver(post_save,sender=Job):
def create_delivery(sender,instance,created,**kwargs):
###
You are assuing that create_delivery
will be called first. But that does not seem to happen. alert_admin
appears to be called first. So what ever signal disabling that you do in create_delivery
just goes waste.
Django does not provide any guarantees or controls over the order in which signals are fired (what's the order of post_save receiver in django?)
You can add a simple flag to your instance to tell the signal processor that this signal does not need further processing.
if hasattr(instance,'signal_processed'):
return
else:
# do whatever processing
instance.signal_processed = True