删除与模型关联的文件 - django

Ale*_*and 3 python django

我的一个模型中有以下代码

class PostImage(models.Model):
    post =  models.ForeignKey(Post, related_name="images")
    # @@@@ figure out a way to have image folders per user...
    image = models.ImageField(upload_to='images')
    image_infowindow = models.ImageField(upload_to='images')
    image_thumb = models.ImageField(upload_to='images')
    image_web = models.ImageField(upload_to='images')
    description = models.CharField(max_length=100)
    order = models.IntegerField(null=True)

    IMAGE_SIZES = {
        'image_infowindow':(70,70),
        'image_thumb':(100,100),
        'image_web':(640,480),
    }

    def delete(self, *args, **kwargs):
        # delete files..
        self.image.delete(save=False)
        self.image_thumb.delete(save=False)
        self.image_web.delete(save=False)
        self.image_infowindow.delete(save=False)
        super(PostImage, self).delete(*args, **kwargs)
Run Code Online (Sandbox Code Playgroud)

我正在尝试删除调用delete()方法时的文件PostImage.但是,文件未被删除.

如您所见,我重写了delete()方法,并删除了每个方法ImageField.但是出于某种原因,文件未被删除.

mik*_*725 8

您可以使用多种方法删除模型实例.

一种方法是通过调用delete():

PostImage.objects.get(...).delete()
Run Code Online (Sandbox Code Playgroud)

在这种情况下delete()调用,因此将删除文件.但是,您也可以使用querysets删除对象:

PostImage.objects.filter(...).delete()
Run Code Online (Sandbox Code Playgroud)

区别在于使用后一种方法,Django将使用SQL DELETE命令批量删除对象,因此delete()不会调用每个对象的方法.因此,您可能正在使用查询集删除对象,因此不会删除文件.

您可以使用post_deleteDjango信号解决此问题,如下所示:

@receiver(post_delete, sender=PostImage)
def post_delete_user(sender, instance, *args, **kwargs):
    instance.image.delete(save=False)
    instance.image_thumb.delete(save=False)
    instance.image_web.delete(save=False)
    instance.image_infowindow.delete(save=False)
Run Code Online (Sandbox Code Playgroud)

请注意,如果使用此方法,则不必再覆盖该delete()方法.

更多关于这里和这里

  • 好答案.可能值得注意的是,由于其系统中的非事务完整性,Django明确**不会删除上传的文件,因为[正当理由](https://code.djangoproject.com/ticket/6456)如果你需要回滚删除操作,你不能因为原来上传的文件已经消失了. (4认同)