Skip to main content
 首页 » 编程设计

python之由 django 提供服务时获取一个空文件

2025年05月04日35youxin

我有以下代码用于通过 django 管理文件下载。

def serve_file(request, id): 
 
    file = models.X.objects.get(id=id).file #FileField 
    file.open('rb') 
    wrapper = FileWrapper(file) 
    mt = mimetypes.guess_type(file.name)[0] 
    response = HttpResponse(wrapper, content_type=mt) 
 
    import unicodedata, os.path 
    filename = unicodedata.normalize('NFKD', os.path.basename(file.name)).encode("utf8",'ignore') 
    filename = filename.replace(' ', '-') #Avoid browser to ignore any char after the space 
 
    response['Content-Length'] = file.size 
    response['Content-Disposition'] = 'attachment; filename={0}'.format(filename) 
 
    #print response 
    return response 

不幸的是,我的浏览器在下载时得到一个空文件。

打印的响应似乎是正确的:

Content-Length: 3906 
Content-Type: text/plain 
Content-Disposition: attachment; filename=toto.txt 
 
blah blah .... 

我有类似的代码运行正常。我不明白可能是什么问题。有什么想法吗?

PS:我已经测试了提出的解决方案here并获得相同的行为

更新: 将 wrapper = FileWrapper(file) 替换为 wrapper = file.read() 似乎可以解决问题

更新:如果我评论 print response,我会遇到类似的问题:。该文件是空的。唯一的区别:FF 检测到 20 字节的大小。 (文件比这个大)

请您参考如下方法:

文件对象是一个可交互的,也是一个生成器。它只能在被耗尽之前阅读一次。然后你必须创建一个新的,使用一种方法再次从对象的开头开始(例如:seek())。

read() 返回一个字符串,可以多次读取没有问题,这就是它解决你问题的原因。

所以只要确保如果你使用像对象这样的文件,你就不会连续读取它两次。 E.G:不打印,然后退回。