如何在用户上传新文件时删除现有文件

时间:2016-09-19 16:42:21

标签: python django django-models

我刚刚成功实现了一个类似于Giles建议的方法,用于保存具有模型主键的文件名的新图像: https://stackoverflow.com/a/16574947/5884437

使用的实际代码:

class Asset(models.Model):
    asset_id = models.AutoField(primary_key=True)
    asset_image = models.ImageField(upload_to = 'images/temp', max_length=255, null=True, blank=True)

    def save( self, *args, **kwargs ):
        # Call save first, to create a primary key
        super( Asset, self ).save( *args, **kwargs )

        asset_image = self.asset_image
        if asset_image:
            # Create new filename, using primary key and file extension
            oldfile = self.asset_image.name
            dot = oldfile.rfind( '.' )
            newfile = 'images/' + str( self.pk ) + oldfile[dot:]

            # Create new file and remove old one
            if newfile != oldfile:
                self.asset_image.storage.delete( newfile )
                self.asset_image.storage.save( newfile, asset_image )
                self.asset_image.name = newfile 
                self.asset_image.close()
                self.asset_image.storage.delete( oldfile )

        # Save again to keep changes
        super( Asset, self ).save( *args, **kwargs )

    def __str__(self):
        return self.asset_description

e.g。用户在空白的“新资产”表单上提交“MyPicture.jpg”。服务器首先预先保存新资产以生成(asset_id)主键,然后将文件重命名为[asset_id]。[original_extension](例如“26.jpg”)并将其移动到正确的文件夹。

不幸的是,我刚刚发现这不考虑具有不同扩展名的文件,例如用户首先上传重命名为“26.jpg”的图像,但是当用户上传具有不同扩展名的该资产的新图像(例如“.png”)时,“26.jpg”和“ “26.png”将彼此并存。

如何更改此设置,以便在为该资产/主键上传新图像时始终删除现有图像?

1 个答案:

答案 0 :(得分:2)

当旧图像与新收集的图像不匹配时,您可以尝试删除旧图像:

class Asset(models.Model):
    asset_id = models.AutoField(primary_key=True)
    asset_image = models.ImageField(upload_to = 'images/temp', max_length=255, null=True, blank=True)

    def save( self, *args, **kwargs ):
        # Delete the old image
        try:
            asset = Asset.objects.get(id=self.id)
            if asset.asset_image and self.image and asset.asset_image != self.image:
                # Delete the old file if it doesn't match the newly submitted one
                asset.asset_image.delete(save=False);
        except Asset.DoesNotExist:
            # Do nothing when a new image is submitted
            pass
        # Call save first, to create a primary key
        super( Asset, self ).save( *args, **kwargs )
        ...

更好的解决方案可能是查看django-cleanup,它会自动删除FileField,ImageField和子类的文件。它将在删除模型时或在更新新文件时删除旧文件。