Domanda

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.

È stato utile?

Soluzione

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/

Altri suggerimenti

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top