Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

django post_save signals on update

I am trying to set up some post_save receivers similar to the following

@receiver(post_save, sender=Game, dispatch_uid='game_updated') def game_updated(sender, **kwargs):      '''DO SOME STUFF HERE'''      MyPick.objects.filter(week=game.week, team=game.home_team).update(result=home_result)     MyPick.objects.filter(week=game.week, team=game.away_team).update(result=away_result)   @receiver(post_save, sender=MyPick, dispatch_uid='user_pick_updated') def update_standings(sender, **kwargs):     '''DO STUFF''' 

The first receiver is getting called correctly after an update on the Game object, however the calls to update on the MyPick object are not causing the second receiver to be called. Does the post_save signal not work on update or am I missing something else here?

Thanks

like image 887
user417918 Avatar asked Sep 11 '11 02:09

user417918


People also ask

Where is Pre_save signal in Django?

pre_save. This is sent at the beginning of a model's save() method. Arguments sent with this signal: sender.

Are Django signals asynchronous?

For the uninitiated, signals are synchronously (this will be important later) firing events that trigger handlers. There are a few common built in ones, we'll be discussing post_save and pre_save signals that are triggered whenever a Django model is saved.

How do you call a signal in Django?

Sending signals There are two ways to send signals in Django. To send a signal, call either Signal. send() (all built-in signals use this) or Signal. send_robust() .

Should I use Django signals?

Only use signals to avoid introducing circular dependencies. If you have two apps, and one app wants to trigger behaviour in an app it already knows about, don't use signals. The app should just import the function it needs and call it directly.


2 Answers

update() is converted directly to an SQL statement; it doesn't call save() on the model instances, and so the pre_save and post_save signals aren't emitted. If you want your signal receivers to be called, you should loop over the queryset, and for each model instance, make your changes and call save() yourself.

like image 98
Ismail Badawi Avatar answered Sep 30 '22 23:09

Ismail Badawi


Just one more thing to @Ismali Badawi's answer.


This calls post_save

user = User.objects.get(id=1)  user.username='edited_username'  user.save() 

This does not call post_save

User.objects.filter(id=1).update(username='edited_username') 

In the code,

from django.db.models.signals import post_save  @receiver(post_save, sender=User) def do_something_when_user_updated(sender, instance, created, **kwargs):     if not created:         # User object updated         user_obj = instance         pass 
like image 27
Chemical Programmer Avatar answered Sep 30 '22 22:09

Chemical Programmer