在Django中删除已上传的文件

10
我有以下代码用于删除文件:
from django.db import models
from django import forms
import os

class Document(models.Model):
    docfile = models.FileField(upload_to='documents/%Y/%m/%d')
    def __unicode__(self):
        return '%s' % (self.docfile.name)
    def delete(self, *args, **kwargs):
        os.rmdir(os.path.join(settings.MEDIA_ROOT, self.docfile.name))
        super(Document,self).delete(*args,**kwargs)

它成功地删除了我在views.py中要求它删除的对象,但当我重新上传同名文件时,似乎原始文件仍然存在,因为我会得到“output_1.txt”而不是“output.txt”。
这是我用来删除的代码:
def delete_matrix():
    documents = Document.objects.all()
    documents.delete()

我没有从数据库中删除文件吗?任何帮助都将不胜感激。

4个回答

14

你的问题是,你在模型上重写了delete()方法,但你却在调用默认管理器(Documents.object.all().delete())返回的QuerySet上调用了delete方法。这是两个不同的方法,因此有两种解决方法。

1. 在模型的delete方法中,替换掉这一行

os.rmdir(os.path.join(settings.MEDIA_ROOT, self.docfile.name))
os.remove(os.path.join(settings.MEDIA_ROOT, self.docfile.name))

并且,为每个对象单独调用删除方法。请替换

Document.objects.all().delete()
documents = Document.objects.all()
for document in documents:
    document.delete()

2.替换默认管理器以返回自定义QuerySet,该对象覆盖了delete()方法。这在Django中覆盖QuerySet.delete()中有解释。


没有异常,os.remove 似乎也无法解决错误。 - user2569766
我们得到了相同的答案!昨晚我修复了这个问题,我意识到我根本不应该覆盖删除方法,我只是在 document.delete() 后添加了 os.remove(...)。 - user2569766

1

试试这个

document = Document.objects.get(pk=pk)
# if `save`=True, changes are saved to the db else only the file is deleted
document.docfile.delete(save=True)

0

您可以使用更简单的代码:

def delete(self, *args, **kwargs):
    if self.docfile:
        self.docfile.delete()
    super().delete(*args, **kwargs)

0

这里是另一种解决方案

def delete(self, *args, **kwargs):
   os.remove(os.path.join(settings.MEDIA_ROOT, self.qr_code.name))
   super().delete(*args, **kwargs)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接