首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >跨多个记录从FileField/ImageFields批量删除文件

问跨多个记录从FileField/ImageFields批量删除文件
EN

Stack Overflow用户
提问于 2013-06-24 15:43:34
回答 2查看 230关注 0票数 2

我有一个名为Picture的模型,它有一个ImageField字段picture_file。

在删除Picture时,我使用post_delete信号从文件系统中删除该文件:

代码语言:javascript
复制
def delete_picture(sender, **kwargs):
    picture_file = kwargs.get('instance')
    picture.picture_file.storage.delete(picture.picture_file.path)
post_delete.connect(delete_picture, Picture)

但是批量删除不会触发post delete信号,因此对于bulk_deletes,我想在单个操作中收集所有路径并进行删除。这是可能的吗?在这种情况下,一次删除操作会有好处吗?

所有文件的存储方法应该是相同的,所以如果有一个批量文件删除命令/模块,我认为这将是理想的?

EN

回答 2

Stack Overflow用户

发布于 2013-06-24 15:54:30

批量删除的概念是有效地执行它,因此它将更新运行任何信号或其他方法。

您可以很容易地更改您的管理器,在批量删除之前,您需要删除所有路径,然后删除文件(或为您的celery或cron工作进程放置此列表),然后从数据库中删除对象,如下所示:

代码语言:javascript
复制
class MyManager(models.Manager)
     def delete_with_files(self, **kwargs):
          qs = self.get_query_set().filter(**kwargs)
          files = list(qs.values_list('picture_file__path', flat=True))
          delete_all_files(files)
          qs.delete()
票数 0
EN

Stack Overflow用户

发布于 2013-06-24 17:44:25

好吧,这不是我正在寻找的答案,但这是我很满意的解决方案,直到出现更好的解决方案:

而不是调用:

代码语言:javascript
复制
Picture.objects.all().delete()

它依次为每一行调用以下post_delete信号:

代码语言:javascript
复制
def delete_picture(sender, **kwargs):
    picture_file = kwargs.get('instance')
    picture.picture_file.storage.delete(picture.picture_file.path)

我改为断开信号连接,然后删除循环中的文件,然后在以下位置运行bulk_delete:

代码语言:javascript
复制
signals.post_delete.connect(delete_picture, sender=Picture)

pics = Picture.objects.all()
for pic in pics:
    signals.post_delete.connect(delete_picture_files, sender=PictureFile)
pics.delete()

使用timeit,在单次运行500条记录/文件时,速度从34下降到1.6秒。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17270365

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档