Django message save message calls twice despite uid

I registered my callback signal with @receiver decorator

 @receiver(post_save, sender=User, dispatch_uid='ARandomUniqueString') def do_callback(sender, **kwargs): 

I put the code from app.signals import * in __init__.py and I see that it is imported twice, and I don’t think there is a good way to fix it, possibly because of installed apps in settings.py . I don’t understand why, despite the fact that when using dispatch_uid and modelInstance.save is only called once, it still runs do_callback twice. Any suggestions?

+7
source share
4 answers

So, I moved the import to views.py (or models.py ), and while it was imported only once, it was called twice.

The problem was that the post_save signal was called when the object was created and also saved. I have no idea why I added a workaround that works now.

 created = False #Workaround to signal being emitted twice on create and save if 'created' in kwargs: if kwargs['created']: created=True #If signal is from object creation, return if created: return 

Edit:

post_save was called twice because I used .create(...) , which is equivalent to __init__(...) and .save() .

Conclusion

dispatch_uid works and makes single import is still good practice.

+9
source

I put the code from app.signals import * in __init__.py

You should not put anything in your __init__.py file.

If you remove this from __init__.py and add it to the end of models.py , it should solve your problem.

You should also avoid blind imports from foo import *

+1
source

I had the same issue with post_save as well as post_delete. It seems that the session object and LogEntry object were saved, and also generated several signals, despite setting dispatch_uid.

What worked for me:

 from django.contrib.admin.models import LogEntry from django.contrib.sessions.models import Session .... if sender in [LogEntry, Session]: return else: # do your thing here 
+1
source

I ran into the same problem. I have a receiver that does something important that needs to be done only once for each new model instance creation in Django. So, I used the post_save signal, but it was called twice to create each instance of a new model, which I did as Profile.objects.create(...) . The solution to this problem is the created flag, which comes with kwargs . Here, how you can use this flag to make sure that your intended action is performed only once:

 @receiver(post_save, sender=Profile) def publish_auction(sender, **kwargs): if kwargs['created']: kwargs['instance'].send_email_confirmation() 

I tried the dispatch_uid Django docs suggestion. This did not work, but the code I pasted above works.

+1
source

All Articles