在多重删除时重写删除函数

0 投票
3 回答
1415 浏览
提问于 2025-04-15 18:00

当我在对象的管理页面上选择删除时,下面的代码运行得很好。问题是,当我使用多选功能一次删除多个项目时,它没有使用我自定义的删除方法。我一直在寻找解决办法,但还没有找到,所以我决定向高手们请教一下;)

class Photo(models.Model):
    name = models.CharField(max_length=256, unique=True)
    slug = models.SlugField(unique=True)
    image = models.ImageField(upload_to='photos/')

    def delete(self):
        super(Photo, self).delete()
        ### Check if the dir is empty, then remove the folder
        ph = Photo.objects.filter(album=self.album)
        if ph.count() == 0:
            rmtree(os.path.join(settings.MEDIA_ROOT, 'photos/' + self.album.slug))     

3 个回答

0

当你使用多选功能并一次性删除多个项目时

我猜这意味着你可能在做类似这样的事情:

Photo.objects.filter(name='something').delete()

如果是这样的话,这样做不会调用你自定义的 delete 方法,因为它使用的是查询集上的 delete 方法。虽然这样效率不高,但你可以通过以下方式强制调用你的删除方法:

for photo in Photo.objects.filter(name='something'):
    photo.delete()
1

为了完整性说明,模型的删除方法并不会在 Model.objects.filter(...).delete() 这个调用中被执行: https://docs.djangoproject.com/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.delete

在调用 Model.objects.filter(...).delete() 后,Django 会发送两个信号,分别是 pre_delete 和 post_delete。更多信息可以查看这里: https://docs.djangoproject.com/en/dev/ref/signals/#pre-delete

3

我解决了我的问题 :)

class PhotoQuerySet(QuerySet):
    def delete(self):
        for x in self:
            x.delete()

class PhotoManager(models.Manager):
    def get_query_set(self):
        return PhotoQuerySet(self.model)

class Photo(models.Model):
    name = models.CharField(max_length=256, unique=True)
    slug = models.SlugField(unique=True)
    image = models.ImageField(upload_to='photos/')

    objects = PhotoManager()

    def delete(self):
        os.remove(self.get_thumbnail_name())
        os.remove(self.get_medium_name())
        super(Photo, self).delete()

撰写回答