前端埋一個隱藏的表單,用於傳值:
<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();
}
}
})
});
這樣就可以下載文件了,後臺根據前端值不同選擇不同的文件發送。
下載效果如下: