Django,关于zip文件响应的问题

iva*_*123 1 python django zip

我在django中作为附件发送请求时遇到问题.我的应用程序将一些数据写入文件并对其进行拉链.但是,当我返回附件响应时,浏览器会下载它,但zip文件已损坏.(原始zip包含我的文件,不会出现任何错误.)

我的代码在这里:

        file_path = "/root/Programs/media/statics/schedules/"
        zip_file_name = file_path + "test.zip"
        zip_file = zipfile.ZipFile(zip_file_name, "w")
        for i in range(len(planner_list)):
                file_name = file_path + str(planner_list[i][0].start_date)
                render_to_file('deneme.html',file_name ,{'schedule':schedule})
                zip_file.write(file_name, os.path.basename(file_name),zipfile.ZIP_DEFLATED)
                os.remove(file_name)
        zip_file.close()

        response = HttpResponse(file_path , content_type='application/zip')
        response['Content-Disposition'] = 'attachment; filename=test.zip'
        return response
Run Code Online (Sandbox Code Playgroud)

Pau*_*ine 9

HttpResponse接受一个字符串或迭代器返回字符串(就像一个打开文件的对象).您正在传递文件路径,因此响应包含一个文件,其内容只是文件路径而不是您写入文件的有效zip内容.您可以使用,open因为HTTPResponse对象将为您关闭文件:

response = HttpResponse(open(file_path, 'rb'), content_type='application/zip')
Run Code Online (Sandbox Code Playgroud)

引用文档:

最后,您可以传递HttpResponse迭代器而不是字符串.HttpResponse将立即使用迭代器,将其内容存储为字符串,然后丢弃它.具有close()方法的对象(如文件和生成器)会立即关闭.

如果需要将响应从迭代器流式传输到客户端,则必须使用StreamingHttpResponse类.

在每个请求上写入磁盘可能会损害您的服务器I/O - 查看您的代码,一切看起来都足够小以适应内存.您可以使用(C)StringIO(Python3中的BytesIO)而不是真实文件:

from io import BytesIO

mem_file = BytesIO()
with zipfile.ZipFile(mem_file, "w") as zip_file:
    for i, planner in enumerate(planner_list):
        file_name = str(planner[0].start_date)
        content = render_to_string('deneme.html', {'schedule':schedule})
    zip_file.writestr(file_name, content)

f.seek(0)  # rewind file pointer just in case
response = HttpResponse(f, content_type='application/zip')
Run Code Online (Sandbox Code Playgroud)