我有一个带有可选头像的用户配置文件模型,看起来像
#models.py
class UserProfile(models.Model):
avatar = models.ImageField(upload_to=avatars null=True, blank=True)
.
.
.
然后像这样的表格:
#forms.py
class UserProfileForm(forms.ModelForm):
avatar = forms.ImageField(required=False,....)
class Meta:
model = UserProfile
最后,一个 View 包括
#views.py
def edit_profile(....)
profile_obj = request.user.userprofile
form = UserProfile(data=request.POST, files=request.FILES, instance=profile_obj)
if form.is_valid():
form.save()
现在,当呈现用于编辑用户个人资料和头像的模板时,它包含一个 Clear
复选框,选中后让用户删除他们的头像照片。它离开了myuser.avatar
在州<ImageFieldFile: None>
,但是它不会删除站点本身存储区域中的文件(即 jpg、png 或其他)。我在 Django 1.6
中读到这是设计使然,这一切都很好,但我如何覆盖此功能,以便文件确实被删除到?
从 shell 来看没有问题:
from myapp.models import UserProfile
user1==UserProfile.objects.all()[0]
user1.avatar.delete()
删除 jpeg
也是。
编辑:
我尝试使用如下信号:
#models.py
.
.
.
@receiver(post_delete, sender=UserProfile)
def avatar_post_delete_handler(sender, **kwargs):
print 'DEBUG: avatar delete triggered'
avatar = kwargs['instance']
storage, path = avatar.original_image.storage, avatar.original_image.path
storage.delete(path)
但这甚至没有触发,我猜是因为我没有删除 UserProfile
目的
当用户选择清除复选框而不是仅选择头像时,完整显示。
最佳答案
像这样扩展 ImageField 并改为使用它:
class ImageField(models.ImageField):
def save_form_data(self, instance, data):
if data is not None:
file = getattr(instance, self.attname)
if file != data:
file.delete(save=False)
super(ImageField, self).save_form_data(instance, data)
如果您将旧文件替换为新文件,这将删除旧文件,或者将其标记为清除。 Here是为什么的解释。
编辑:
还有一个应用django-smartfields它包括此功能以及更多功能,例如自动调整大小、图像和视频的自动转换等。不过,它以更复杂的方式实现它,使用字段描述符和模型自定义。但是使用起来非常简单:
from smartfields import fields
class UserProfile(models.Model):
avatar = fields.ImageField(upload_to='avatars', blank=True)
它还会在以下情况下删除文件:
- 字段值已替换为新值(上传或手动设置)
- 包含字段的模型实例本身被删除。
关于python - Django:如何在勾选清除复选框时自动从存储中删除文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22082052/