2

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

我正在使用 post_delete 信号从文件系统中删除文件,因为Pictures 被删除:

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)

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

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

4

2 回答 2

0

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

而不是调用:

Picture.objects.all().delete()

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

def delete_picture(sender, **kwargs):
    picture_file = kwargs.get('instance')
    picture.picture_file.storage.delete(picture.picture_file.path)

我改为断开信号,然后在循环中删除文件,然后在之后运行 bulk_delete:

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 条记录/文件的单次运行中,这会从几秒下降341.6几秒。

于 2013-06-24T09:44:25.317 回答
0

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

您可以轻松更改您的经理,在批量删除之前,您可以删除所有路径,然后删除文件(或为您的 celery 或 cron 工作人员放置此列表),然后从数据库中删除对象,如下所示:

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()
于 2013-06-24T07:54:30.483 回答