python - Django:如何在勾选清除复选框时自动从存储中删除文件?

标签 python django storage

我有一个带有可选头像的用户配置文件模型,看起来像

#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/

相关文章:

python - Pandas 加入分类索引

python - Django - 服务用户上传的图片

Django通过子模型计数(一对多关系)对父模型进行排序

python - 生成和发送 MS Outlook 任务

python - 如何使用 Python (pytwist) 获取 CSV 输出中字段的内容而不是 `<bound method...`

python:如何将列添加到numpy中的记录数组

带 Stripe 的 Python/Django : Error in Post request in creating stripe subscription

php - 使用 PHP 在 MySQL 中插入注册数据

xcode - 在 NSUserDefaults Xcode 中存储和更新 Swift 字典

java - 在 Android 上读/写外部存储