前端埋一个隐藏的表单,用于传值:
<form id="hidden_form">
{% csrf_token %}
<input type="hidden" id="flag" name="flag">
<input type="hidden" id="country" name="country">
<input type="hidden" id="datatype" name="datatype">
</form>
python后端如下:(这段代码用于动态生成一个文件)
from django.views.decorators.csrf import csrf_exempt
# 需要提供一个参数type
# 下载功能
# 屏蔽掉csrf
@csrf_exempt
def download_file(request):
import os
from django.http import HttpResponse, FileResponse
from django.shortcuts import render
if request.method == "GET":
return render(request, "COVID_19Analyse/filedown.html")
# 获取操作类型
try:
type = request.POST.get("datatype")
except Exception as e:
return HttpResponse("你所访问的页面不存在", status=404)
print(type)
if type=="details":
try:
country = request.POST.get("country")
print(country)
except Exception as e:
return HttpResponse("你所访问的页面不存在", status=404)
else:
country=""
from ...tools.ExcelOpt import ExcelSpool
excel = ExcelSpool()
print(type)
path = os.path.abspath(os.path.dirname(__file__))
path = os.path.abspath(os.path.dirname(path) + os.path.sep + "..")
the_file_name = getFileName(type,country)
if the_file_name==False:
print("111")
return HttpResponse("你所访问的页面不存在", status=404)
# 文件名 存储路径
filename = path + '/static/COVID_19Analyse/Upload/' + the_file_name
print(filename)
if judge_exit(filename)==False:
# 不存在该文件
# 获取数据
createFile(filename,type,country)
# 发送文件
file = open(filename, "rb")
response = FileResponse(file)
response['Content-Type'] = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
response['Content-Disposition'] = 'attachment; ' \
'filename=' + the_file_name.encode('utf-8').decode('ISO-8859-1')
return response
def judge_exit(file_path):
import os
if(os.path.exists(file_path)):
return True
return False
def getFileName(type,country=""):
if type == "maincountry":
the_file_name = "主要国家.xlsx"
elif type == "plc":
the_file_name = "人口大国.xlsx"
elif type == "continent":
the_file_name = "大洲情况.xlsx"
pass
elif type == "trend":
the_file_name = "全球趋势.xlsx"
elif type == "rank":
the_file_name = "全球榜单.xlsx"
elif type == "details":
the_file_name = "country/"+country+".xlsx"
else:
return False
return the_file_name
def createFile(filename,type,country=""):
from ...tools.ExcelOpt import ExcelSpool
from .data.ToExcelData import ToExcelData
excel = ExcelSpool()
if type == "maincountry":
results = ToExcelData.getMainCountryDetails()
excel.dictdictlist2excel(filename, results)
elif type == "plc":
results = ToExcelData.peopleLargeCountryConfirm()
excel.dict_2DList2excel(filename, results)
elif type == "continent":
results = ToExcelData.continentConfirm()
excel.dict_2DList2excel(filename, results)
pass
elif type == "trend":
results = ToExcelData.getOverseaTrend()
excel.dictlist2excel(filename, "海外疫情数据", results)
elif type == "rank":
results = ToExcelData.getRank()
excel.dictdictlist2excel(filename, results)
elif type == "details":
from ...models import Country
try:
countryDataModels = (Country.objects.get(name=country).countrydata_set.all().order_by("-date"))
excel.modellist2excel(filename, country, countryDataModels)
except Exception as e:
print(str(e))
return False
因为用ajax实现的时候,其实是提交了两遍表单的,第二次的表单提交才是下载,我的错误就是第二次没有使用参数,因此后台识别不了,无法动态生成文件,控制台如下:
可以看见第一次表单是有值的,第二次没有,因此考虑第二次时,构造一个参数表单提交。JS代码如下:
$("a[name='rankdata']").bind("click", function () {
$("#datatype").val("rank");
var input1 = $('<input>');
input1.attr('type', 'hidden');
input1.attr('name', 'datatype');
input1.attr('value', $("#datatype").val());
var input2 = $('<input>');
input2.attr('type', 'hidden');
input2.attr('name', 'country');
input2.attr('value', $("#country").val());
$.ajax({
url: "/data/download/",
type: "POST",
data: $("#hidden_form").serialize(),
success: function (response, status, request) {
var disp = request.getResponseHeader('Content-Disposition');
if (disp && disp.search('attachment') != -1) { //判断是否为文件
var form = $('<form action="/data/download/" method="post"></form>');
$('body').append(form);
form.append(input1);
form.append(input2);
form.submit();
}
}
})
});
这样就可以下载文件了,后台根据前端值不同选择不同的文件发送。
下载效果如下: