我一直在为这个问题绞尽脑汁。 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))
不是这样做的。如果有人能帮助我,我将不胜感激。
答案 0 :(得分:4)
如果您尝试将所有文件打包在一个zip中,可以将其存档在Admin
中类似的东西:
def zipFiles(files):
outfile = StringIO() # io.BytesIO() for python 3
with zipfile.ZipFile(outfile, 'w') as zf:
for n, f in enumarate(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'
答案 1 :(得分:0)
我已经满足了这个需求。我的解决方案是使用 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>