web-dev-qa-db-ja.com

post_deleteを使用してファイルシステムからファイルを削除する方法-Django 1.8

サムネイル画像を含むモデル-製品があります。製品に関連付けられた画像を含む別のモデルがあります-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',)

次のdeleteメソッド(製品クラス内)は機能していましたが、コードを変更したため機能しなくなりました。読んだ内容から、delete()をオーバーライドするのではなくpost_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インスタンスの削除に関してどのように適用すればよいかわからないため、これまでのところ失敗しています...

13
tim

そして、これが_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 deleteについて読む: docs

20
sobolevn

1.11Djangoで。コード作業!

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)

Django Cleanupを使用します

https://github.com/un1t/Django-cleanup

pip install Django-cleanup
1