Python Flask技术问询:文件处理后展示模型指标并提供下载
问题描述
我在PythonAnywhere上部署了Python Flask项目,流程为用户上传文件→通过RandomForestRegressor模型处理→生成结果文件供下载,目前流程运行正常。现在希望把模型的测试集准确率、训练集MSE等指标展示在网页上(比如显示Accuracy of model on test set: 0.90、mse of model on train set: 0.08这类信息)。
我的HTML模板用Jinja2循环渲染comments列表,代码如下:
<html> <body> {% for comment in comments %} <div class="row"> {{ comment }} </div> {% endfor %} </body> </html>
我尝试在调用proccess_data函数后设置comments变量并调用render_template,但未生效,相关代码片段:
output_file = proccess_data(filename) comments = 'File processed succesfully' render_template("main_page.html", comments=comments)
完整Flask代码如下:
comments = [] @app.route('/', methods=["GET","POST"]) def index(): if request.method == "GET": return render_template("main_page.html") if request.method == 'POST': #comments.append(request.form["contents"]) #check if the post request has the file part if 'input_file' not in request.files: #TODO return redirect(request.url) file = request.files['input_file'] #if the user does not select a file, the browser submits #empty file without a filename if file.filename == '': #TODO return redirect(request.url) if file and allowed_file(file.filename): filename = secure_filename(file.filename) file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename)) output_file = proccess_data(filename) comments = 'File processed succesfully' render_template("main_page.html", comments=comments) si = io.StringIO() output_file.to_csv(si,index=False, encoding='UTF8') #-----Save dataframe to folder----- filepath = os.path.join(app.config['UPLOAD_FOLDER'], 'results.csv') output_file.to_csv(filepath) response = make_response(si.getvalue()) response.headers["Content-Disposition"] = "attachment; filename=results.csv" response.headers["Content-type"] = "text/csv" return response return
需要修改代码,实现文件处理完成后同时展示模型指标和提供结果文件下载。
解决方案
核心问题梳理
当前代码有两个关键问题:
- 调用
render_template后未返回,而是直接返回下载响应,导致页面无法更新展示指标; - HTTP单次请求只能返回一个响应,无法同时返回页面和下载文件,必须拆分流程。
具体修改步骤
1. 改造proccess_data函数,返回模型指标
让数据处理函数同时返回结果文件和模型评估指标:
def proccess_data(filename): # 原有数据处理、模型训练逻辑... # 假设已计算完成模型指标 test_accuracy = 0.90 train_mse = 0.08 # 返回结果DataFrame和指标字典 return output_file, {"test_accuracy": test_accuracy, "train_mse": train_mse}
2. 调整Flask视图函数逻辑
采用「处理后重定向+会话存储指标+独立下载路由」的方案:
from flask import session, url_for, send_from_directory # 必须配置SECRET_KEY,session依赖此密钥 app.secret_key = 'your-custom-secret-key-here' # 替换为实际密钥 @app.route('/', methods=["GET","POST"]) def index(): if request.method == "GET": # 从session读取临时存储的模型指标,读取后清空session metrics = session.pop('model_metrics', None) comments = [] if metrics: # 将指标转换为模板可渲染的列表格式 comments = [ f"Accuracy of model on test set: {metrics['test_accuracy']}", f"MSE of model on train set: {metrics['train_mse']}", "File processed successfully" ] return render_template("main_page.html", comments=comments) if request.method == 'POST': if 'input_file' not in request.files: return redirect(request.url) file = request.files['input_file'] if file.filename == '': return redirect(request.url) if file and allowed_file(file.filename): filename = secure_filename(file.filename) file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename)) # 获取结果文件和模型指标 output_file, model_metrics = proccess_data(filename) # 将指标存入session,供GET请求读取展示 session['model_metrics'] = model_metrics # 生成唯一结果文件名,避免多用户上传时文件覆盖 result_filename = f"results_{filename.split('.')[0]}.csv" filepath = os.path.join(app.config['UPLOAD_FOLDER'], result_filename) output_file.to_csv(filepath, index=False, encoding='UTF8') # 重定向到首页,此时GET请求会读取session中的指标并展示 return redirect(url_for('index')) return redirect(request.url) # 添加独立的文件下载路由 @app.route('/download/<filename>') def download_file(filename): return send_from_directory(app.config['UPLOAD_FOLDER'], filename, as_attachment=True)
3. 更新HTML模板,添加下载链接
修改模板,在展示指标的同时显示下载入口:
<html> <body> {% for comment in comments %} <div class="row"> {{ comment }} </div> {% endfor %} {% if comments %} <div class="row" style="margin-top:10px;"> <a href="{{ url_for('download_file', filename='results.csv') }}">点击下载结果文件</a> <!-- 若使用了唯一文件名,需将文件名传入模板,或从session中读取后传递 --> </div> {% endif %} </body> </html>
4. 额外注意事项
- 文件名唯一化:建议给结果文件添加时间戳或用户标识前缀,避免多用户操作时文件被覆盖;
- 旧文件清理:PythonAnywhere存储空间有限,需定期清理上传的源文件和结果文件;
- session有效期:session默认会随浏览器关闭失效,若需要持久化可调整配置。
内容的提问来源于stack exchange,提问作者rzenva
相关产品推荐
相关产品推荐

