21

我有一个模型 - 产品,其中包含一个缩略图。我有另一个模型,其中包含与产品相关的图像 - ProductImage。当产品实例被删除时,我想从服务器中删除缩略图和图像,有一段时间这似乎有效,但不再有效。

相关代码...

Class Product(models.Model):
    title = Charfield
    thumbnail = ImageField(upload_to='thumbnails/', verbose_name='thumbnail', blank=True, )

Class ProductImage(models.Model):
    product = models.ForeignKey(plant, default=None, related_name='images')
    image = models.ImageField(upload_to='images/', verbose_name='image',)

以下删除方法(在产品类中)有效,但我更改了代码,但它不再有效 - 从我所阅读的内容来看,最好的做法是使用 post_delete,而不是覆盖 delete()

def delete(self):
    images = ProductImage.objects.filter(product=self)
    if images:
        for image in images:
            image.delete()
    super(Product, self).delete()

我怎样才能重写一个删除方法来实现我想要的?我曾尝试使用 post_delete 但到目前为止我一直没有成功,因为我不确定在删除 ProductImage 实例时如何应用它......

4

3 回答 3

40

这是一个例子post_delete

import os
from django.db import models

def _delete_file(path):
   """ Deletes file from filesystem. """
   if os.path.isfile(path):
       os.remove(path)

@receiver(models.signals.post_delete, sender=ProductImage)
def delete_file(sender, instance, *args, **kwargs):
    """ Deletes image files on `post_delete` """
    if instance.image:
        _delete_file(instance.image.path)

@receiver(models.signals.post_delete, sender=Product)
def delete_file(sender, instance, *args, **kwargs):
    """ Deletes thumbnail files on `post_delete` """
    if instance.thumbnail:
        _delete_file(instance.thumbnail.path)

覆盖delete()方法:

class Product(models.Model):
    ...

    def delete(self):
        images = ProductImage.objects.filter(product=self)
        for image in images:
            image.delete()
        self.thumbnail.delete()
        super(Product, self).delete()


class ProductImage(models.Model):
    ...

    def delete(self):
        self.image.delete()
        super(ProductImage, self).delete()

阅读有关Cascade删除:文档

于 2015-10-12T12:21:18.073 回答
5

在 1.11 Django 中。代码工作!

import os
from django.db import models
from django.utils import timezone

from django.db.models.signals import pre_delete
from django.dispatch.dispatcher import receiver

class Post(models.Model):
    category = models.ForeignKey(Category, verbose_name='Категория')
    title = models.CharField('Заголовок', max_length=200, unique=True)
    url = models.CharField('ЧПУ', max_length=200, unique=True)
    photo = models.ImageField('Изображение', upload_to="blog/images/%Y/%m/%d/", default='', blank=True)
    content = models.TextField('Контент')
    created_date = models.DateTimeField('Дата', default=timezone.now)


def _delete_file(path):
    # Deletes file from filesystem.
    if os.path.isfile(path):
        os.remove(path)


@receiver(pre_delete, sender=Post)
def delete_img_pre_delete_post(sender, instance, *args, **kwargs):
    if instance.photo:
        _delete_file(instance.photo.path)
于 2017-08-16T00:13:36.563 回答
0

要有效地从系统中删除文件,请尝试:

文件 = modelName.objects.all().get(columnName=criteria)

文件.columnNameFile.delete() 文件.columnNameFile2.delete() 。. .

于 2022-02-18T20:07:09.300 回答