How to delete files from filesystem using post_delete - Django 1.8

后端 未结 3 1976
栀梦
栀梦 2020-12-30 05:08

I have a model - Product, which contains a thumbnail image. I have another model which contains images associated with the product - ProductImage. I want to delete both the

相关标签:
3条回答
  • 2020-12-30 05:13

    In 1.11 Django. Code work!

    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)
    
    0 讨论(0)
  • 2020-12-30 05:20

    Use Django Cleanup

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

    pip install django-cleanup
    
    0 讨论(0)
  • 2020-12-30 05:25

    And here's an example with the 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)
    

    Overriding the delete() method:

    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()
    

    Read about Cascade delete: docs

    0 讨论(0)
提交回复
热议问题