models.py:
class Car(models.Model):
...
class Pictures(models.Model):
car = models.ForeignKey(Car, related_name='pictures')
width = models.PositiveIntegerField(editable=False, default=780)
height = models.PositiveIntegerField(editable=False, default=585)
image = models.ImageField(upload_to = get_file_path, max_length=64, height_field='height', width_field='width')
def __unicode__(self):
return str(self.id)
def delete(self, *args, **kwargs):
storage, path = self.image.storage, self.image.path
super(Pictures, self).delete(*args, **kwargs)
storage.delete(path)
效果很好(我从管理面板中删除了一张图片,这张图片会自动从磁盘中删除)。
但是当我通过管理面板删除Car对象时,图像不会从磁盘中删除。
如何解决这个问题?
谢谢!
答案 0 :(得分:1)
我确定这里的问题是ORM使用ON DELETE CASCADE
让数据库句柄删除关系,这意味着你的delete
方法不会被调用。
您可能只应用您在此处使用的相同技术并执行此操作:
class Car(models.Model):
...
def delete(self, *args, **kwargs):
for picture in self.pictures.all():
storage, path = picture.image.storage, picture.image.path
storage.delete(path)
super(Car, self).delete(*args, **kwargs)
但是,最好使用信号而不是覆盖delete
方法https://docs.djangoproject.com/en/dev/ref/signals/#post-delete
请注意,使用QuerySet批量删除对象时,不一定要调用对象的delete()方法。为确保执行自定义删除逻辑,您可以使用pre_delete和/或post_delete信号。
答案 1 :(得分:0)
我开始研究这个问题,发现了一些关于管理和删除对象的有趣事情。
从admin中删除对象时,将调用以下函数,
django / contrib / admin / options.py - > delete_model()
反过来调用obj.delete()
,其中obj是当前被删除的对象。
对象的delete方法然后运行以下代码,
collector = Collector(using=using)
collector.collect([self])
collector.delete()
收集器对象现在有一个属性'data',其中包含所有相关对象。
当collector.delete()
运行时,它执行函数query.delete_batch(pk_list, self.using)
,该函数使用参数pk_list执行批量删除,该参数是要删除的相关对象的主键列表。批量删除功能又不会调用每个相关对象的删除方法。
这里的好处是会为所有相关对象调用pre_save和post_save信号,因此我们可以将自定义删除代码移动到图片模型的pre_save或post_save信号中。
这应该有效,但我没有机会进行测试。