我有一个简单的Flask应用程序,它可以进行CSV上传,进行一些更改,并将结果作为CSV流返回到用户的下载文件夹。
HTML表单
<form action = {{uploader_page}} method = "POST" enctype = "multipart/form-data">
<label>CSV file</label><br>
<input type = "file" name = "input_file" required></input><br><br>
<!-- some other inputs -->
<div id = "submit_btn_container">
<input id="submit_btn" onclick = "this.form.submit(); this.disabled = true; this.value = 'Processing';" type = "submit"></input>
</div>
</form>
Python
from flask import Flask, request, Response, redirect, flash, render_template
from io import BytesIO
import pandas as pd
@app.route('/uploader', methods = ['POST'])
def uploadFile():
uploaded_file = request.files['input_file']
data_df = pd.read_csv(BytesIO(uploaded_file.read()))
# do stuff
# stream the pandas df as a csv to the user download folder
return Response(data_df.to_csv(index = False),
mimetype = "text/csv",
headers = {"Content-Disposition": "attachment; filename=result.csv"})
这工作得很好,我在我的下载文件夹中看到了文件。
但是,我希望在下载完成后显示“* 下载完成 *”页面。
我该怎么做?通常我使用return redirect("some_url")
来更改页面。
3条答案
按热度按时间8xiog9wr1#
请考虑使用
send_file()
或send_from_directory()
发送文件。从一个请求中得到两个响应是不可能的,但是您可以在一些JS的帮助下将问题拆分成块,遵循下面这个简单的图表(不是非常精确的UML,但就是这样):
flash()
之后,该版本被更新 *1.通过
onsubmit
从表单中调用的函数POST到/uploader
,这样除了保存文件之外,还可以在那里使用一些逻辑,比如检查响应状态1.处理文件(我通过
upper()
模拟了您的处理过程)1.如果服务器响应
201
(“Created”),则可以保存文件并输出“Download Complete”(我使用window.document.body.innerHTML
是因为它只有一个标记,我们可以替换所有以前的DOM;不应使用它来更改复杂的HTML)1.否则,如果服务器以其他状态代码(如
500
)响应,则POST到/something-went-wrong
以获得要呈现的新的(可能是闪存的)HTML。要测试错误页面,请在
upload_file()
内部的处理中进行一些语法错误,例如data_df = pd.read_csv(BytesIO(uploaded_file.
aread()))
在
something-went-wrong
响应中,我添加了一个CSP头来减轻可能的恶意攻击,因为我们不能足够信任用户。代码如下:
主文件.py
具有JS处理程序的表单:
为了完整起见,我的虚拟csv
"file.csv"
:| 浮|
| - -|
| 棒|
icnyk63a2#
这里是一些变化。
在输入onclick事件中设置
window.open('')
HTML表单
sy5wg1nm3#
您需要两个函数,一个用于处理诸如uploadFile()之类的处理,另一个位于同一个应用程序路由中,用于返回渲染模板。
uploadFile()函数完成后:
completed = True
然后,编写另一个函数,该函数测试全局变量
if completed:
以返回渲染模板。请参阅:How can I use the same route for multiple functions in Flask
最后,使用Jinja2返回一个变量到页面,并使用Javascript确定该变量是否存在,以便通过Javascript加载“download completed”页面。
巨蟒:
如何加载新页面:https://www.geeksforgeeks.org/how-can-a-page-be-forced-to-load-another-page-in-javascript/
Javascript条件:https://www.w3docs.com/learn-javascript/conditional-operators-if.html
使用Jinja2呈现变量:https://jinja.palletsprojects.com/en/3.0.x/templates/
此外,您还应该使用try和except来 Package uploadFile()函数,以捕获上载错误。