Python Flask框架下数据库变更时自动刷新HTML视图的实现咨询
Flask实现用户页面数据变更自动刷新方案
小提示:你现有代码中
update_user_holdings路由存在变量使用错误,路由传入的user_name是字符串类型,不能直接取.bid属性,需要先执行user = Users.query.filter_by(user_name=user_name).first()查询出用户对象后再操作业务逻辑。
你可以根据自己对实时性的要求选择以下两种实现方案:
方案1:前端短轮询(改造成本最低)
逻辑为前端固定间隔主动拉取最新数据,局部更新页面,无需全页刷新,适合对实时性要求不高的场景。
- 后端新增返回JSON格式持股数据的接口:
@app.route('/get_user_holdings/<user_name>') def get_user_holdings(user_name): user = Users.query.filter_by(user_name=user_name).first() return {"share_amount": user.share_amount}
- 前端
user_page.html添加轮询逻辑:
<!-- 假设你页面上展示持股数量的元素id为share_amount --> <script> // 每3秒拉取一次最新数据 setInterval(async () => { const res = await fetch(`/get_user_holdings/{{ user.user_name }}`); const data = await res.json(); document.getElementById('share_amount').textContent = data.share_amount; }, 3000); </script>
方案2:WebSocket实时推送(体验最优)
基于Flask-SocketIO实现全双工通信,数据更新后服务端主动推送给前端,实时性高、服务端压力小。
- 安装依赖
pip install flask-socketio eventlet - 后端改造代码:
from flask_socketio import SocketIO, emit, join_room # 初始化socketio socketio = SocketIO(app, cors_allowed_origins="*") # 原有user_page路由无需修改 @app.route('/update_page/<user_name>', methods=['GET', 'POST']) def update_user_holdiongs(user_name): # 先修正原有变量错误,查询用户对象 user = Users.query.filter_by(user_name=user_name).first() # 保留原有业务逻辑 if user.bid > last_bid: change = TradeBids.query.filter_by(id=user.id).update(dict(share_amount=user.share_amount - bid.share_amount)) db.session.add(bid) db.session.commit() # 新增:给对应用户推送更新通知 socketio.emit('holdings_updated', {'new_amount': user.share_amount}, room=user_name) return "更新成功" # 新增WebSocket连接处理逻辑 @socketio.on('join') def handle_join(user_name): join_room(user_name) # 启动方式替换为socketio.run if __name__ == '__main__': socketio.run(app, debug=True)
- 前端
user_page.html添加SocketIO逻辑:
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.0.1/socket.io.js"></script> <script> const socket = io(); // 页面加载后加入对应用户的消息房间 socket.emit('join', '{{ user.user_name }}'); // 监听服务端更新通知 socket.on('holdings_updated', (data) => { // 局部更新持股数量 document.getElementById('share_amount').textContent = data.new_amount; // 如果需要全页刷新可以打开下面的注释 // location.reload() }); </script>
内容的提问来源于stack exchange,提问作者Monty_emma
相关产品推荐
相关产品推荐

