How to use post_save signal ?

430 views
Skip to first unread message

Nikhil Verma

unread,
Mar 4, 2012, 10:31:50 AM3/4/12
to django...@googlegroups.com
Hi all

I am using Django-1.2.5 and i want to use post_save signal in the following problem/task.

I have :-
models.py

image = models.ImageField(.....)
remove_image = models.BooleanField()

Now i want  :-

1) When the user uploads the file , the file path appears on the imageField like this.

Currently: images/testimonial-bottom_1.png

Change:

I want to give the option to delete the file .So i made a field called remove image which is a checkbox . Now when the user clicks that remove_image checkbox and press save the image should get deleted. I was going through the documentation and believe that this problem could be solved by using post_save signal


I have not used signals so need help ,


def delete_old_image(sender, instance, using=None,*args, **kwargs):
    try:
        old_record = sender.objects.get(pk=instance.pk)
        old_record.delete()
    except sender.DoesNotExist:
        pass
signals.post_save.connect(delete_old_image, sender=Trip)

How can i achieve this task by using signals or without signals.

Any help will be appreciated.


--
Regards
Nikhil Verma
+91-958-273-3156

akaariai

unread,
Mar 4, 2012, 12:52:22 PM3/4/12
to django...@googlegroups.com
You have a misunderstanding in your code: when you fetch the old_record from sender.objects you are actually refetching the instance being saved. Then you do on to delete the instance. Is this really what you want?

Now, if you want to delete the file in a signal, you should use pre_save signal, where you delete the image using instance.image.delete(save=False) or better jet set instance.image = None (see later for details). You should probably also clear the "save" flag, as otherwise that gets saved into the DB.

Still, it is much better to handle the clearing of the image field by using a custom form, and then do the clearing of the image in some hook of the form or in the view directly (for ModelForm that would be overridden .save()). The checkbox remove_image isn't really part of your data model, so it should not be a field in you model class, just a user input element.

Last, for some technicalities about file handling in transactional setting: To do file handling properly when using transactional databases you should actually do the file delete post-commit. The reason is this sequence of events:
  - delete file
  - do save
  - for some reason the transaction is rolled back. (network error, integrity error in DB, electricity lost and so on).

Now you have a model in the DB whose file field points to the now deleted file. The delete can't be rolled back.

So, to be technically correct, you should do the .delete() in post-commit hook. Now the worst case is that the transaction gets committed, but for some reason the file can't be deleted (crash of the server at the wrong moment). But, this results just in a leftover file in the storage. That is easy to clean up and in most cases doesn't matter at all.

As said, this is just a technicality. Django doesn't even provide that post-commit hook. I think I am going to suggest a pre/post commit signal, that could have other uses, too... However: there is a lesson here: are you sure you want to actually delete the actual file? You could just remove the link from the instance to that file, but leave the file in the file system.

 - Anssi

Nikhil Verma

unread,
Mar 4, 2012, 1:12:20 PM3/4/12
to django...@googlegroups.com
Hi akaariai

As you said i will remove the file and leave the file in file system(mistake for writing delete).
Now what i have done is :-

image: Currently: images/testimonial-bottom_2.png
Change: Delete this file

When you click the link Delete this file what it will do is it will remove the path "images/testimonial-bottom_2.png ".But the problem begins when you press save button and open the same row in django - admin it appears again as if it was not removed and actually it is not removed from that ImageField . i have checked by going through shell.

Actually i want implement ImageField of Django1.4b . It  has a checkbox(remove_image) along with the ImageField asking for clear image and when you click on that the image get  removed. How can i get the same thing working for Django1.2.5 which i am using.

So i thought to make a checkbox ,click on that it will trigger a post_save signal which first looks if the checkbox of remove_image is checked and when save  button is pressed it wil remove the path of image.

How can i implement that ? Thanks for help in advance .



--
You received this message because you are subscribed to the Google Groups "Django users" group.
To view this discussion on the web visit https://groups.google.com/d/msg/django-users/-/j3k9QXOZkYcJ.
To post to this group, send email to django...@googlegroups.com.
To unsubscribe from this group, send email to django-users...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/django-users?hl=en.

akaariai

unread,
Mar 4, 2012, 1:53:17 PM3/4/12
to django...@googlegroups.com
On Sunday, March 4, 2012 3:12:20 PM UTC+2, Nikhil Verma wrote:
Hi akaariai

As you said i will remove the file and leave the file in file system(mistake for writing delete).
Now what i have done is :-

image: Currently: images/testimonial-bottom_2.png
Change: Delete this file

When you click the link Delete this file what it will do is it will remove the path "images/testimonial-bottom_2.png ".But the problem begins when you press save button and open the same row in django - admin it appears again as if it was not removed and actually it is not removed from that ImageField . i have checked by going through shell.

Actually i want implement ImageField of Django1.4b . It  has a checkbox(remove_image) along with the ImageField asking for clear image and when you click on that the image get  removed. How can i get the same thing working for Django1.2.5 which i am using.


One way is to check the source code of 1.4b and see what it does.
 
So i thought to make a checkbox ,click on that it will trigger a post_save signal which first looks if the checkbox of remove_image is checked and when save  button is pressed it wil remove the path of image.

How can i implement that ? Thanks for help in advance .


I have a bit hard time following what is the exact thing you want. So, the best advice I can give you is this: don't use the post_save signal. Use pre_save signal or better yet, a custom ModelForm. You must do the clearing of the image field _before_ the data gets saved into the database, and you can't do that from post_save signal.

 - Anssi

Nikhil Verma

unread,
Mar 4, 2012, 5:29:59 PM3/4/12
to django...@googlegroups.com
Hi akaariai

I solved my problem by using snippet 1633 FileField/ImageField. Thanks for making my concept in signals.


--
You received this message because you are subscribed to the Google Groups "Django users" group.
To view this discussion on the web visit https://groups.google.com/d/msg/django-users/-/ORkjtr8LBHoJ.

To post to this group, send email to django...@googlegroups.com.
To unsubscribe from this group, send email to django-users...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/django-users?hl=en.
Reply all
Reply to author
Forward
0 new messages