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