Django在更新文件后正确删除图像 [英] Django correctly delete image after updating file
问题描述
有一个类似的问题这里,但那是从2011和Django 1.2。从那以后,很多事情都发生了变化。我正在使用Django 1.9。
There is a similar question here but that is from 2011 and Django 1.2. Many things have changed since then. I'm using Django 1.9.
我想知道如何正确地执行此操作,没有任何可能弄乱文件系统的风险。我在模型中有一个 ImageField
:
I'm wondering how should I do this correctly, without any risks of messing up the filesystem. I have an ImageField
in a model:
class CartaMagicPy(models.Model):
imagen = models.ImageField(null=True, upload_to=ubicar_magicpy)
第一时刻,图像被保存。但是,然后,用户裁剪图像,并获得分配给相同的 ImageField
的新图像。
On a first moment, the image is saved. But then, the user crops the image and I get a new image assigned to the same ImageField
.
旧图像不会从文件系统中删除。如何删除它?问题是更新后的 model_object.imagen.path
包含新的图像的路径。如果我在之前删除它,请用新图像进行更新,否则我有可能会失败,然后我完全没有图像。有没有可以使用的后保存信号的组合?任何建议都有帮助。
The old image is not deleted from the filesystem. How can I delete it? The problem is that model_object.imagen.path
after being updated contains the path to the new image. And if I delete it before I update it with the new image, I risk that maybe the save could fail and then I end up with no image at all. Is there a combination of post-save signals I could use? Any advice will help.
推荐答案
As 在这个答案中看到,有一个应用程序: django-cleanup 。
As seen in this answer, "there's an app for that": django-cleanup.
如果你喜欢自己实现,在评论中链接的问题@raphv接受的答案给了一些很好的指针。
If you prefer to implement it yourself, the accepted answer to the question @raphv linked in the comment gives some good pointers.
更新更新跟踪的一个很好的解决方案是使用模型信号;我倾向于使用 post_init
和 post_save
,在这种情况下,删除之后的旧图片文件。如下所示:
A good solution for updated change followup is to use model signals; I tend to use post_init
and post_save
, in this case to delete the old image file after the change has been made. Something like so:
from django.db.models.signals import post_init, post_save
from django.dispatch import receiver
from myapp.models import CartaMagicPy
@receiver(post_init, sender= CartaMagicPy)
def backup_image_path(sender, instance, **kwargs):
instance._current_imagen_file = instance.imagen
@receiver(post_save, sender= CartaMagicPy)
def delete_old_image(sender, instance, **kwargs):
if hasattr(instance, '_current_imagen_file'):
if instance._current_imagen_file != instance.imagen.path:
instance._current_imagen_file.delete(save=False)
这似乎通常是上面链接的包,加上一些额外的安全检查和清理。
This also seems to be generally what the linked package above does, plus some additional safety checks and cleanup.
这篇关于Django在更新文件后正确删除图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!