如何在httpresponse django中返回多个文件



我在这个问题上一直在困扰我的大脑。Django有没有办法从单个httpresponse中提供多个文件?

我有一个场景,我正在循环浏览JSON列表,并希望将所有这些作为文件形式返回我的管理员视图。

class CompanyAdmin(admin.ModelAdmin):
    form = CompanyAdminForm
    actions = ['export_company_setup']
    def export_company_setup(self, request, queryset):
        update_count = 0
        error_count = 0
        company_json_list = []
        response_file_list = []
        for pb in queryset.all():
            try:
                # get_company_json_data takes id and returns json for the company.
                company_json_list.append(get_company_json_data(pb.pk))
                update_count += 1
            except:
                error_count += 1
        # TODO: Get multiple json files from here.
        for company in company_json_list:
            response = HttpResponse(json.dumps(company), content_type="application/json")
            response['Content-Disposition'] = 'attachment; filename=%s.json' % company['name']
            return response
        #self.message_user(request,("%s company setup extracted and %s company setup extraction failed" % (update_count, error_count)))
        #return response

现在,这只会让我返回/下载一个JSON文件,因为返回将打破循环。是否有一种简单的方法可以将所有这些附加在一个响应对象中,然后返回外部循环并在多个文件中下载列表中的所有JSON?

我浏览了一种将所有这些文件包装到zip文件中的方法,但是我没有这样做,因为我可以找到的所有示例都有带有路径和名称的文件,而在这种情况下,我实际上没有这些示例。

更新:

我尝试集成Zartch的解决方案以使用以下方式获取ZIP文件:

    import StringIO, zipfile
    outfile = StringIO.StringIO()
    with zipfile.ZipFile(outfile, 'w') as zf:
        for company in company_json_list:
            zf.writestr("{}.json".format(company['name']), json.dumps(company))
        response = HttpResponse(outfile.getvalue(), content_type="application/octet-stream")
        response['Content-Disposition'] = 'attachment; filename=%s.zip' % 'company_list'
        return response

由于我从来没有文件开始,所以我想只是使用我拥有的JSON转储并添加单个文件名。这只是创建一个空的Zipfile。我认为这是可以预期的,因为我确定zf.writestr("{}.json".format(company['name']), json.dumps(company))不是这样做的方法。如果有人能帮助我,我会很感激。

也许如果您尝试将所有文件包装在一个zip中,则可以在Admin

中存档。

类似:

    def zipFiles(files):
        outfile = StringIO()  # io.BytesIO() for python 3
        with zipfile.ZipFile(outfile, 'w') as zf:
            for n, f in enumerate(files):
                zf.writestr("{}.csv".format(n), f.getvalue())
        return outfile.getvalue()
    zipped_file = zip_files(myfiles)
    response = HttpResponse(zipped_file, content_type='application/octet-stream')
    response['Content-Disposition'] = 'attachment; filename=my_file.zip'

我满足了此需求。我的解决方案是使用html href和javascript

使用服务器生成下载文件列表的列表

<a href="http://a.json" download='a.json'></a>
<a href="http://b.json" download='b.json'></a>
<a href="http://c.json" download='c.json'></a>
<a href="http://d.json" download='d.json'></a>
<a href="http://e.json" download='e.json'></a>
<script>
    //simulate click to trigger download action
    document.querySelector('a').forEach( aTag => aTag.click());
</script>

最新更新