4

I want to run some code after my model is saved. Three places to do this will be

1) override save method:

def save(self, *args, **kwargs): super(Blog, self).save(*args, **kwargs) do_something() 

2) use post_save signal:

def model_created(sender, **kwargs) the_instance = kwargs['instance'] if kwargs['created']: do_something() post_save.connect(model_created, sender=YourModel) 

3) do this in the view itself.

if form.is_valid(): do_something() return redirect(reverse("homepage")) 

All three should work. This post advocates the second one.

My question is that the second method (post_save) works when the model is first created. I want to call do_something() whenever a new model is created and also when an existing model is updated. In the latter case, I will have kwargs[created] to be false. how do I handle this situation?

P.S: I am currently doing the third one which works fine for both updateView and CreateView. but the problem is it takes time to return from the do_something() function before it is being redirected.

7
  • Why don't omit if kwargs['created'] check in the post_save signal handler? Commented May 7, 2014 at 19:07
  • I want it to handle when both model is created or when it is updated. without the check, the first is not recommended Commented May 7, 2014 at 19:36
  • Remove the if kwargs['created'] check and do_something() would be called whenever model is created or updated. Commented May 7, 2014 at 19:57
  • yes, I understand what you mean. but I guess it is a not a good practice to call something before checking it is created.. Commented May 7, 2014 at 20:03
  • 1
    That's probably the way to go. There are packages that allow you to use the signals API while specifying that something should execute asynchronously on celery (for example async-signals, though I haven't used it personally). Commented May 8, 2014 at 18:48

1 Answer 1

4

post_save signal is the cleanest option among these three.

Just eliminate if kwargs['created'] and call do_something() right in the body of a function:

def model_created_or_updated(sender, **kwargs): the_instance = kwargs['instance'] do_something() post_save.connect(model_created_or_updated, sender=YourModel) 

Now, every time YourModel is created or updated do_something() would be called.

FYI, created is just a flag that indicates whether YourModel was created (value is True) or updated (value is False).

Note that do_something() will be executed synchronously and will be "blocking" until done. If you want to execute do_something asynchronously, you need to go with a real task management tool, like celery package.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.