使用Django生成要下载的文件

Jos*_*unt 95 python django

是否可以制作一个zip存档并提供下载,但仍然不能将文件保存到硬盘?

muh*_*huk 111

要触发下载,您需要设置Content-Disposition标题:

from django.http import HttpResponse
from wsgiref.util import FileWrapper

# generate the file
response = HttpResponse(FileWrapper(myfile.getvalue()), content_type='application/zip')
response['Content-Disposition'] = 'attachment; filename=myfile.zip'
return response
Run Code Online (Sandbox Code Playgroud)

如果您不想要磁盘上的文件,则需要使用 StringIO

import cStringIO as StringIO

myfile = StringIO.StringIO()
while not_finished:
    # generate chunk
    myfile.write(chunk)
Run Code Online (Sandbox Code Playgroud)

您也可以选择设置Content-Length标题:

response['Content-Length'] = myfile.tell()
Run Code Online (Sandbox Code Playgroud)

  • 使用此示例下载一个始终为空的文件,任何想法? (4认同)
  • 正如@ eleaz28所说,它也是在我的情况下创建空白文件.我刚刚删除了`FileWrapper`,它工作正常. (3认同)
  • 我以读取模式打开文件,然后 file.getvalue() 给出属性错误:TextIOWrapper 没有属性 getValue 。 (2认同)

S.L*_*ott 26

你会更乐意创建一个临时文件.这节省了大量内存.如果同时拥有多个或两个用户,您会发现节省内存非常非常重要.

但是,您可以写入StringIO对象.

>>> import zipfile
>>> import StringIO
>>> buffer= StringIO.StringIO()
>>> z= zipfile.ZipFile( buffer, "w" )
>>> z.write( "idletest" )
>>> z.close()
>>> len(buffer.getvalue())
778
Run Code Online (Sandbox Code Playgroud)

"缓冲区"对象与文件类似,带有778字节的ZIP存档.

  • 关于节省内存的好点子。但是如果使用临时文件,你会把删除它的代码放在哪里? (2认同)

小智 10

为什么不做一个tar文件呢?像这样:

def downloadLogs(req, dir):
    response = HttpResponse(content_type='application/x-gzip')
    response['Content-Disposition'] = 'attachment; filename=download.tar.gz'
    tarred = tarfile.open(fileobj=response, mode='w:gz')
    tarred.add(dir)
    tarred.close()

    return response
Run Code Online (Sandbox Code Playgroud)


Sov*_*iut 9

是的,您可以使用zipfile模块,zlib模块或其他压缩模块在内存中创建zip存档.您可以使视图将zip存档写入HttpResponseDjango视图返回的对象,而不是将上下文发送到模板.最后,您需要将mimetype设置为适当的格式,以告知浏览器将响应视为文件.


小智 6

models.py

from django.db import models

class PageHeader(models.Model):
    image = models.ImageField(upload_to='uploads')
Run Code Online (Sandbox Code Playgroud)

views.py

from django.http import HttpResponse
from StringIO import StringIO
from models import *
import os, mimetypes, urllib

def random_header_image(request):
    header = PageHeader.objects.order_by('?')[0]
    image = StringIO(file(header.image.path, "rb").read())
    mimetype = mimetypes.guess_type(os.path.basename(header.image.name))[0]

    return HttpResponse(image.read(), mimetype=mimetype)
Run Code Online (Sandbox Code Playgroud)


Kam*_*ngi 5

def download_zip(request,file_name):
    filePath = '<path>/'+file_name
    fsock = open(file_name_with_path,"rb")
    response = HttpResponse(fsock, content_type='application/zip')
    response['Content-Disposition'] = 'attachment; filename=myfile.zip'
    return response
Run Code Online (Sandbox Code Playgroud)

您可以根据您的要求替换zip和内容类型.