Question

I want to update one field of my model after post save. For that I am using post_save signal but when I try to save the model it always get trapped in some kind of infinite loop and in the end I am getting max, recursion depth error

My code is as follows :

class UserProfile(models.Model):
   . 
   .
  . 

def profile_thumbanil(sender, created, instance , **kwargs):
    profile = UserProfile.objects.get(id = instance.id)
    thumb = handlers.create_thumbanil(profile.image, profile.user_id)
    profile.thumbnail_image = thumb
    profile.save()

post_save.connect(profile_thumbanil, sender=UserProfile)

I don't know what's the error here. If anyone can tell me another way of saving the data after post_save then that will be also fine.

Thanks

Edit :

save() will not work in my case because I am creating the thumbnail of images and the script which I using resize the images which are already exist on server and thus untill the save() finished its work image will not be saved on server and thus I cannot resize it that's why I can only run my function after save() finished its work so that image will be saved on server and I can resize it.

I can use Update() when user try to save images via UI and in that case my function works because Image is already saved into db but when admin (django-admin) try to upload an image then issue comes. So I need to call my function in such a way that whenever django admin save/edit profile images I can call my function but as I said my function only works after actual save() finished its work.

Était-ce utile?

La solution

You can redefine save method of the model. It is more appropriate in your case than using signals because you modify the same instance.

Maybe this would be helpful: http://www.martin-geber.com/thought/2007/10/29/django-signals-vs-custom-save-method/

Autres conseils

You can get the object using filter and then use the update method to save the corresponding field.

def profile_thumbanil(sender, created, instance , update_fields=["thumbnail_image"], **kwargs):
    profile = UserProfile.objects.get(id = instance.id)
    thumb = handlers.create_thumbanil(profile.image, profile.user_id)
    profile.update(thumbnail_image = thumb)

post_save.connect(profile_thumbanil, sender=UserProfile)

An alternative method is to disconnect the post save signal, save relevant fields then reconnect the post save method.

We need to be super careful when using save() inside post_save, they can lead to a recursive call. Here is one solution.

def profile_thumbanil(sender, created, instance , update_fields=["thumbnail_image"], **kwargs):
    profile = UserProfile.objects.get(id = instance.id)
    thumb = handlers.create_thumbanil(profile.image, profile.user_id)
    profile.save(update_fields=["thumbnail_image"])

post_save.connect(profile_thumbanil, sender=UserProfile)

Internally this would use an update SQL command instead of insert.

UPDATE row
SET    "thumbnail_image" = 'your image'
WHERE  "row"."id" = pk

This will work for sure, however, the best practice would be to use save() method instead.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top