我刚刚成功实现了一个类似于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”将彼此并存。
如何更改此设置,以便在为该资产/主键上传新图像时始终删除现有图像?
答案 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和子类的文件。它将在删除模型时或在更新新文件时删除旧文件。