我有一个名为Picture
的模型,它有一个ImageField字段picture_file
。
我正在使用post_delete信号从文件系统中删除文件,因为Picture
被删除了:
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,我想收集所有路径并在一次操作中删除。这是可能的吗,在这种情况下,单个删除操作是否有益?
对于所有文件,存储方法应该是相同的,所以如果有批量文件删除命令/模块,我认为这是理想的吗?
答案 0 :(得分:0)
批量删除的概念是有效的,所以它会更新的运行任何信号或其他方法。
您可以轻松地更改您的经理,在批量删除之前,您将获取所有要删除的路径,然后删除文件(或将此列表放入您的芹菜或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()
答案 1 :(得分: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次记录/文件的单次运行中,从34
下降到1.6
秒。