Kil*_*elo 18 django model bulk imagefield
我正在重写Django的模型删除方法,以便删除磁盘中用于图像字段的孤立文件,如下所示:
class Image(models.Model):
img = models.ImageField(upload_to=get_image_path)
...
def delete(self, *args, **kwargs):
self.img.delete()
super(Image, self).delete(*args, **kwargs)
Run Code Online (Sandbox Code Playgroud)
当我从管理员中删除单个对象时这很好用,但是当我选择多个对象并删除它们时,似乎没有被调用.我已经谷歌搜索了一段时间,但没有找到正确的关键字来得到答案,也没有官方文档似乎谈论这个主题.
Gwy*_*idD 36
它确实:
delete()方法执行批量删除,不会在模型上调用任何delete()方法.但是,它会为所有已删除的对象(包括级联删除)发出pre_delete和post_delete信号.
要使其正常工作,您可以覆盖删除方法QuerySet
,然后将其应用QuerySet
为管理器:
class ImageQuerySet(models.QuerySet):
def delete(self, *args, **kwargs):
for obj in self:
obj.img.delete()
super(ImageQuerySet, self).delete(*args, **kwargs)
class Image(models.Model):
objects = ImageQuerySet.as_manager()
img = models.ImageField(upload_to=get_image_path)
...
def delete(self, *args, **kwargs):
self.img.delete()
super(Image, self).delete(*args, **kwargs)
Run Code Online (Sandbox Code Playgroud)
查询集的删除方法直接在数据库上工作.它不会调用Model.delete()
方法.来自文档:
请记住,只要有可能,这将完全在SQL中执行,因此在此过程中不一定会调用各个对象实例的delete()方法.如果您在模型类上提供了自定义delete()方法并希望确保调用它,则需要"手动"删除该模型的实例(例如,通过迭代QuerySet并调用delete()on每个对象单独)而不是使用QuerySet的批量delete()方法.
如果要覆盖Django管理界面的默认行为,可以编写自定义delete
操作:
https://docs.djangoproject.com/en/1.7/ref/contrib/admin/actions/
另一种方法是覆盖post_delete
(或pre_delete
)信号而不是delete
方法:
https://docs.djangoproject.com/en/1.7/ref/signals/#django.db.models.signals.post_delete
像pre_delete一样,但是在模型的delete()方法和queryset的delete()方法结束时发送.
我相信这个问题已在文档中解决
它说:
批量操作不会调用覆盖的模型方法
请注意,当使用 QuerySet 批量删除对象或作为级联删除的结果时,不一定会调用对象的 delete() 方法。为确保执行自定义删除逻辑,您可以使用 pre_delete 和/或 post_delete 信号。
不幸的是,在批量创建或更新对象时没有解决方法,因为没有调用 save()、pre_save 和 post_save。
正如上面文档中所建议的,我相信更好的解决方案是使用post_delete
信号,如下所示:
from django.db.models.signals import post_delete
from django.dispatch import receiver
class Image(models.Model):
img = models.ImageField(upload_to=get_image_path)
...
@receiver(post_delete, sender=Image)
def delete_image_hook(sender, instance, using, **kwargs):
instance.img.delete()
Run Code Online (Sandbox Code Playgroud)
与覆盖该delete
方法不同,该delete_image_hook
函数也应在批量删除和级联删除时调用。以下是有关使用 Django 信号的更多信息:https : //docs.djangoproject.com/en/1.11/topics/signals/#connecting-to-signals-sent-by-specific-senders
注意以前的答案:
一些较早的帖子建议覆盖delete
QuerySet的方法,这可能会影响性能和其他意外行为。也许这些答案是在 Django 的 Signals 实现之前写的,但我认为使用 Signals 是一种更简洁的方法。
归档时间: |
|
查看次数: |
13858 次 |
最近记录: |