3

I have a model, on which I need to edit objects given certain states.

Using post_save signals I can identify the given state, and from there run the specified method(s).

My issue now is that in these methods I need to save the object after editing, causing end endless save-loop. Is there a 'correct way' to handling this kind of situation, or are there only bad or worse kinds of workarounds?

BSG
  • 1,382
  • 4
  • 14
  • 25

1 Answers1

2

In order to avoid this kind of loop, you need to disconnect at the beginning of your custom method, and then reconnect to signal afterwards :

Inside your method connected to signal :

signals.post_save.disconnect(YourModel.your_custom_method, sender=YourModel)

# Do your stuff

instance.save()

signals.post_save.connect(YourModel.your_custom_method, sender=YourModel)

Note : I'm using "YourModel.your_custom_method because I tend to place it inside the model, this is obviously not mandatory.

EDIT :

This SO question brings the use of update() instead of save() as a cleaner way, it might be what you're looking for.

Django post_save preventing recursion without overriding model save()

Although it might be cleaner I wouldn't think of it as a perfect solution unless properly managed with caching, since you'll be forced to hit the database to retrieve the queryset while you already have the instance in your hands as argument of the signal...

The idea of save_without_signal seems interesting but I wonder how it could be done without the above caveats.

Hope this helps,

Regards,

Community
  • 1
  • 1
Ambroise
  • 1,649
  • 1
  • 13
  • 16
  • Thanks, but sorry, perhaps I should have mentioned my view of bad workarounds. This doesn’t strike me as the most straight forward approach? – BSG Jan 27 '14 at 09:00
  • I have no problem with placing it inside the model, rather the opposite. It's the disconnection of signals that really seems over the top, but this is considered the 'right' way of handling it? – BSG Jan 27 '14 at 09:03
  • Well, some people tend to disapprove of using the signals instead of overriding save(), and while I don't, disconnecting / reconnecting is to my knowledge the only way except for save() overriding to get around saving loops. It is not explicitly described as such in the docs, but again, nothing else regarding this matter is. – Ambroise Jan 27 '14 at 09:20
  • I've edited my answer with a link to another question with something that might be of interest to you (use update() instead of save() to prevent the signal to be fired again ) – Ambroise Jan 27 '14 at 09:28
  • I'll settle with that, but I still feel it's kind of a workaround. Thanks. – BSG Jan 27 '14 at 10:01