Python zipfile未交付给用户

时间:2015-06-19 18:08:25

标签: python django

更新:我创建了zip文件,但响应仍然无法正常工作。这是更新后的代码。

def index(request):
    if request.is_ajax():
        uploaded = request.body
        newstring = "{\"testdata\": [" + uploaded + "]}"
        data = json.loads(newstring)
        num_lines = sum(len(v) for v in data.itervalues())
        testing(data, num_lines)

        zip_subdir = 'testapi'
        zip_filename = '%s.zip' % zip_subdir

        zf = z.ZipFile(zip_filename, mode='w')
        zf.write('Test.xlsx')
        zf.close()

        zip_file = open(zip_filename, 'r')
        response = HttpResponse(zip_file, content_type='application/x-zip-compressed')
        response['Content-Disposition'] = 'attachment; filename=%s' % zip_filename
        return response

为了确保,我删除了zip文件和Excel电子表格,并在运行程序后,两者都已正确创建。 Excel电子表格填充了数据,并将其副本放入生成的zip存档中。但是,它仍然没有被发送给用户。知道响应可能出了什么问题吗?没有出现任何错误,但是zip文件没有被发送。

以下原始问题。

我试图让我的Django应用程序将文件写入zip并将其发送给用户。这是我在我看来的代码中的一部分:

def index(request):
    if request.is_ajax():
        uploaded = request.body
        newstring = "{\"testdata\": [" + uploaded + "]}"
        data = json.loads(newstring)
        num_lines = sum(len(v) for v in data.itervalues())
        testing(data, num_lines)

        zip_subdir = 'testapi'
        zip_filename = '%s.zip' % zip_subdir

        s = StringIO.StringIO()
        zf = z.ZipFile(s, 'w')
        zf.write('Test.xlsx')
        zf.close()

        response = HttpResponse(s.getvalue(), content_type='application/x-zip-compressed')
        response['Content-Disposition'] = 'attachment; filename=%s' % zip_filename
        return response

基本上,用户按下按钮,ajax请求从外部API获取JSON,然后将此JSON数据发送到服务器并放入Excel电子表格(称为' Test.xlsx&# 39)。所有这些都能正常运作。

问题是zip存档(' testapi.zip')未正确创建。奇怪的是,当用户通过表单(而不是使用API​​)上传JSON转储时,它与我之前使用的代码相同,并且之前有效。但是,现在它不会创建一个zip文件。此外,即使我手动放置一个名为' testapi.zip'的zip文件。在正确的目录中,响应不起作用(再次,这曾经工作过 - 在此应用程序的先前版本中,zip文件已发送给用户并自动下载)。没有返回错误,但没有任何反应。

知道可能会发生什么吗?

2 个答案:

答案 0 :(得分:1)

问题似乎在以下代码中 -

s = StringIO.StringIO()
zf = z.ZipFile(s, 'w')

您似乎在缓冲区中打开zipfile,而不是在名称来自zip_filename的位置创建zip文件。

尝试使用文件的路径/名称打开文件,而不是使用StringIO.StringIO()。像这样 -

zf = z.ZipFile(zip_filename,'w')

编辑:

尝试使用绝对路径而不是相对路径。喜欢 -

zip_subdir = '/path/to/zip/file/testapi'

答案 1 :(得分:0)

我不确定这是否真的是最好的方法,但我找到了一种方法来传递文件。基于this question,看起来像发送回文件作为对ajax请求的响应是不可能的。

这是我新的ajax电话:

$("#btn1").click(function() {
    $.ajax({
        url: "https://api.github.com/",
        type: "GET",
        dataType: 'json',
        success: function(data) {
            $.ajax({
                url: "{% url 'index' %}",
                type: "POST",
                data: JSON.stringify(data),
                contentType: false,
                success: function(response, status, request) {
                    var disp = request.getResponseHeader('Content-Disposition');
                    if (disp && disp.search('attachment') != -1) {
                        var form = $('<form method="POST" action="' + "{% url 'index' %}" + '">' + "{% csrf_token %}");
                        $('body').append(form);
                        form.submit();
                    }
                },
                error: function(data) {
                    alert("There was an error posting the data to the server.");
                },
            });
        },
        error: function(data) {
            alert("There was an error retrieving the data from the API.");
        },
    });
});

这里是views.py中的两个请求处理程序:

if request.is_ajax():
    uploaded = request.body
    newstring = "{\"testdata\": [" + uploaded + "]}"
    data = json.loads(newstring)
    num_lines = sum(len(v) for v in data.itervalues())
    testing(data, num_lines)

    zip_subdir = 'testapi'
    zip_filename = '%s.zip' % zip_subdir

    zf = z.ZipFile(zip_filename, mode='w')
    zf.write('Test.xlsx')
    zf.close()

if request.method == 'POST':
    zip_file = open('testapi.zip', 'rb')
    response = HttpResponse(zip_file, content_type='application/x-zip-compressed')
    response['Content-Disposition'] = 'attachment; filename=%s' % 'testapi.zip'
    return response

本质上,ajax GET请求用于从API获取JSON,ajax POST请求(1)将JSON发送到服务器以放入电子表格并压缩到zip存档中,并且(2)创建一个不可见的POST表单,用于将zip文件传递给用户。