如何从Jinja模板将DataFrame传递至Flask路由?
将DataFrame传递至Flask新路由的最优方法
直接把DataFrame的文本内容塞到hidden输入框里不可行——DataFrame的字符串包含换行、空格、特殊符号,会破坏HTML结构,而且传输效率极低。下面是两种靠谱的实现方案:
方案一:利用Flask会话(Session)存储(适合小体量DataFrame)
把DataFrame序列化后存在Session中,表单提交时无需传递数据本身,新路由直接从Session中读取即可。
后端代码示例
from flask import Flask, render_template, session, request import pandas as pd import pickle import base64 app = Flask(__name__) app.secret_key = "your_secure_secret_key" # 必须设置,用于加密会话数据 # 展示DataFrame的路由 @app.route("/show-data") def show_data(): # 模拟生成DataFrame df = pd.DataFrame({"列1": [1, 2, 3], "列2": ["a", "b", "c"]}) # 序列化DataFrame:pickle转字节后用base64编码,避免特殊字符干扰 df_serialized = base64.b64encode(pickle.dumps(df)).decode("utf-8") session["target_df"] = df_serialized return render_template("show_data.html") # 接收数据的新路由 @app.route("/process-data", methods=["POST"]) def process_data(): if "target_df" in session: # 反序列化还原DataFrame df_serialized = session["target_df"] df = pickle.loads(base64.b64decode(df_serialized)) # 这里写你的DataFrame处理逻辑 return f"成功接收DataFrame:\n{df.to_string()}" return "未找到有效数据"
HTML模板代码
<form method="POST" action="{{ url_for('process_data') }}"> <button type="submit">提交处理</button> </form>
方案二:用数据库/临时存储(适合大体量DataFrame)
如果DataFrame数据量很大,Session的存储上限会不够用,这时可以用Redis、SQLite等数据库存序列化后的DataFrame,仅把数据的唯一ID通过表单传递。
后端代码示例(以Redis为例)
from flask import Flask, render_template, request import pandas as pd import pickle import uuid import redis app = Flask(__name__) # 初始化Redis连接 redis_client = redis.Redis(host="localhost", port=6379, db=0, decode_responses=False) @app.route("/show-data") def show_data(): df = pd.DataFrame({"列1": [1, 2, 3], "列2": ["a", "b", "c"]}) # 生成唯一数据ID data_id = str(uuid.uuid4()) # 序列化DataFrame并存入Redis,设置1小时过期时间避免内存浪费 redis_client.setex(data_id, 3600, pickle.dumps(df)) return render_template("show_data.html", data_id=data_id) @app.route("/process-data", methods=["POST"]) def process_data(): data_id = request.form.get("data_id") if data_id and redis_client.exists(data_id): # 从Redis读取并反序列化 df = pickle.loads(redis_client.get(data_id)) # 用完删除数据,释放空间 redis_client.delete(data_id) return f"成功接收DataFrame:\n{df.to_string()}" return "无效或已过期的数据ID"
HTML模板代码
<form method="POST" action="{{ url_for('process_data') }}"> <input type="hidden" name="data_id" value="{{ data_id }}"> <button type="submit">提交处理</button> </form>
注意事项
- 用pickle序列化时要确保数据来源安全,避免恶意代码注入风险;如果追求更安全的序列化方式,可以用
pd.to_json()和pd.read_json()替代pickle。 - Session存储的数据会加密后存在客户端Cookie中,所以不要存敏感数据,且数据量不宜过大。
内容的提问来源于stack exchange,提问作者Sam
相关产品推荐
相关产品推荐

