我有一个带有图像字段的模型,我希望能够使用ModelForm更改图像。更改图像时,应删除旧图像并用新图像替换。
我尝试过在ModelForm的干净方法中这样做:
def clean(self):
cleaned_data = super(ModelForm, self).clean()
old_profile_image = self.instance.image
if old_profile_image:
old_profile_image.delete(save=False)
return cleaned_data
除非用户指示的文件不正确(例如,如果不是图像),导致图像被删除而没有保存任何新图像,否则这一操作效果良好。我想知道哪里是删除旧图像的最佳位置?我的意思是,在删除旧图像之前,我在哪里可以确定新图像是正确的?
编辑:如果可能的话,我更喜欢在ModelForm类中这样做。
一些答案:
ImageField应通过Python Imaging Library验证上传的文件是否为图像。如果不是,表单将不会验证。
ImageField的path属性中应该有一个指向旧文件的路径。
保存新图像后,可以删除旧图像。更好的是,永远不要使用用户的文件名输入作为文件名。这样更安全,您可以只使用相同的文件名,然后每次只覆盖旧文件,就可以放弃删除步骤。
祝你好运。
好的,我想好了如何使用ModelForm以干净的方式完成它。基本上,我创建了一个名为"ChangeImageForm"的类,它将确保在更改图像时删除旧图像。此外,如果图像无效,它也可以工作:
class ChangeImageForm(ModelForm):
def clean(self):
cleaned_data = super(ModelForm, self).clean()
self.old_image = self.instance.image
return cleaned_data
def save(self, commit=True):
instance = super(ChangeImageForm, self).save(commit)
if self.old_image:
self.old_image.delete(save=False)
return instance
现在,我可以通过从ChangeImageForm继承以下内容,轻松地将上述功能添加到具有图像字段的ModelForm中:
class MyModelForm(ChangeImageForm):
class Meta:
model = MyModel # model with an image field
我认为重写ModelForm是最好的方法,而不是在Model类中,因为我只想在某些情况下删除旧图像。