user417918
user417918

Reputation: 843

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?

Upvotes: 45

Views: 52166

Answers (2)

Chemical Programmer
Chemical Programmer

Reputation: 4520

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

Upvotes: 51

Ismail Badawi
Ismail Badawi

Reputation: 37177

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.

Upvotes: 75

Related Questions