删除博客文章后从媒体文件夹中删除图像

时间:2019-04-02 17:12:17

标签: python django

当我从Django博客中删除帖子时,该帖子已成功删除,但是与该帖子关联的所有图像都保留在我的media文件夹中。如何确保这些内容也被删除?

这是我的文件:

models.py

class News(models.Model):
    title = models.CharField(max_length=255)
    body = models.TextField()
    date = models.DateTimeField(auto_now_add=True)
    author = models.ForeignKey(
        get_user_model(),
        on_delete=models.CASCADE,
    )
    thumb = models.ImageField(blank=True, null=True)

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return reverse('news_detail', args=[str(self.id)])

views.py

class NewsDeleteView(LoginRequiredMixin, DeleteView):
    model = News
    template_name = 'news_delete.html'
    success_url = reverse_lazy('news_list')
    login_url = 'login'

    def test_func(self):
        obj = self.get_object()
        return obj.author == self.request.user

news_delete.html

{% extends 'base.html' %}

{% block content %}
    <h1>Delete</h1>
    <form action="" method="post">{% csrf_token %}
      <p>Are you sure you want to delete "{{ news.title }}"?</p>
      <button class="btn btn-danger ml-2" type="submit">Confirm</button>
    </form>
{% endblock content %}

2 个答案:

答案 0 :(得分:2)

post_delete信号处理程序中最简单的方法是

from django.core.files.storage import default_storage

@receiver(post_delete, sender=News)
def delete_associated_files(sender, instance, **kwargs):
    """Remove all files of an image after deletion."""
    path = instance.thumb.name
    if path:
        default_storage.delete(path)

您还可以在所有包含文件字段的模型中使用mixin类:

from django.db.models.signals import post_delete

class FileDeletionMixin(object):
    file_fields = []  # list the names of the file fields

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        post_delete.connect(delete_associated_files, sender=self.__class__,
                            dispatch_uid=f"_file_deletion_mixin_{self._meta.model_name}-{self._meta.app_label}")

def delete_associated_files(sender, instance, **kwargs):
    """Remove all files of an image after deletion."""
    # you may want to add checks to be sure file_fields exists
    # e.g. if isinstance(instance, FileDeletionMixin)
    for field in instance.file_fields:  
        file = getattr(instance, field)  # you may want to catch exception AttributeError here
        if file:
            file.delete(save=False)

class News(FileDeletionMixin, models.Model):
    thumb = FileField # or ImageField
    file_fields = ['thumb']

答案 1 :(得分:0)

Reference程序包将此功能添加到FieldFieldImageField

您可以使用pip install django-cleanup安装它,然后将其添加到settings.py

INSTALLED_APPS = [
    ...
    'django_cleanup',
    ...
]