Question

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.

Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top