首页 > 解决方案 > 在 django 中删除帖子后,帖子图像仍在目录中

问题描述

在 django 中,我的帖子被删除了,但文件没有。我在模型中有一个图像字段,每当作者删除它时我想删除它。我正在使用基于泛型类的视图删除..所以当我删除帖子时,帖子被删除,但图像没有从目录中删除。我尝试了很多方法,但它不起作用。我的模型.py:

class postManager(models.Manager):
  def repost(self, author, parent_obj):
    if parent_obj.parent:
        og_parent = parent_obj.parent
    else:
        og_parent = parent_obj


    obj = self.model(
            parent = og_parent,
            author = author,
            content = og_parent.content,
            image = og_parent.image,
        )
    obj.save()
    return obj



class post(models.Model):
    parent = models.ForeignKey("self", on_delete=models.CASCADE, blank=True, null=True)
    title = models.CharField(max_length=100)
    image = models.ImageField(upload_to='post_pics', null=True, blank=True)
    video = models.FileField(upload_to='post_videos', null=True, blank=True)
    content = models.TextField()
    likes = models.ManyToManyField(User, related_name='likes', blank=True)
    date_posted = models.DateTimeField(default=timezone.now)
    author = models.ForeignKey(User, on_delete=models.CASCADE)

    objects = postManager()

    def __str__(self):
        return self.title

我的意见.py:

@login_required
def post_list(request):
    count_filter = Q(likes=request.user)
    like_case = Count('likes', filter=count_filter, output_field=BooleanField())

    posts = post.objects.annotate(is_liked=like_case).all().order_by('-date_posted')


    return render(request, 'blog/home.html', {'posts': posts, })

class PostDeleteView(LoginRequiredMixin, UserPassesTestMixin, DeleteView):
model = post
fields = ['content', 'image', 'video']
success_url = '/'

def test_func(self):
    post = self.get_object()
    if self.request.user == post.author:
        return True
    return False

我的 urls.py:

path('post/<int:pk>/delete/', PostDeleteView.as_view(), name='post-delete'),

我在模型中使用父级,所以在 delete(self) 参数上不起作用。

标签: djangodjango-models

解决方案


这是正常行为,因为 的实例post仅存储文件的路径,如字符串,而不是实际文件。实际文件存储在文件系统上。

要在删除 的实例时删除实际文件post,您有一些选择:

1.覆盖delete函数 例如

def delete(self, using=None, keep_parents=False):
    self.image.delete()
    super().delete()

2. 添加删除后的信号 虽然使用信号本身并没有什么问题,但在使用之前应该考虑两点:

  1. 一个信号可以为单个操作发送多次,因此您必须处理任何在单个实例上运行多次可能引发错误的代码(例如,尝试删除不存在的文件)
try:
    os.remove(filename)
except OSError:
    pass
  1. 因为信号不在预期的代码流中,如果它有错误,对于经验不足的开发人员来说,追踪它可能会很棘手

3.使用django-cleanup等包


推荐阅读