You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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 

需要修改代码,实现文件处理完成后同时展示模型指标和提供结果文件下载。


解决方案

核心问题梳理

当前代码有两个关键问题:

  1. 调用render_template后未返回,而是直接返回下载响应,导致页面无法更新展示指标;
  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 14:45:41