Flask应用:无提交按钮动态更新下拉框功能实现求助
Flask动态联动下拉框问题
我的Flask应用运行地址为http://XXX.0.0.1:5050/?tickers_get=Company2&open_price_get=23(需替换XXX为实际机器IP)。当前需求:
- 选择Company2时,价格下拉框自动更新为仅显示22、40两个选项,无需点击提交按钮
- 点击提交后,根据选中条件展示对应数据表格
目前无法实现价格下拉框的动态联动,现有代码如下:
app.py
from flask import Flask, render_template, request import pandas as pd import sqlalchemy as sal from sqlalchemy import create_engine import pyodbc import urllib import numpy as np app = Flask(__name__) get_data_through = "manual_entry" @app.route('/') def index(): read_df = pd.DataFrame( [ ['Company1', 23, 10000], ['Company2', 22, 40000], ['Company2', 40, 40000] ], columns=['new_sql_table','Open_price', 'volume'] ) names = set(read_df['new_sql_table'].tolist()) tickers = request.args.getlist('tickers_get') # 原代码:返回所有价格,未做过滤 open_price_to_filter = read_df['Open_price'].tolist() open_price = request.args.getlist('open_price_get') print(open_price) open_price_get_to_number = ''.join(open_price) data = read_df[read_df['new_sql_table'].isin(tickers)] sum_of_volumns = format(sum(data['volume']), ',') return render_template('template.html', **locals()) if __name__ == "__main__": app.run(port = 5050)
template.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel= "stylesheet" type= "text/css" href= "{{ url_for('static',filename='styles/mainpage.css') }}"> <title>Stocks data</title> </head> <body> <h2>Stocks data</h2><h4>Total Volume is : {{sum_of_volumns}} and selected open price is {{open_price_get_to_number}}</h4> <form> <label>Company:</label> <select name="tickers_get"> {% for name in names %} <option value="{{ name }}" {% if name in tickers %}selected{% endif %}>{{name}}</option> {% endfor %} </select> <label>Open Price:</label> <select name="open_price_get" style="width:75px"> {% for op in open_price_to_filter %} <option value="{{ op }}" {% if op in open_price %}selected{% endif %}>{{op}}</option> {% endfor %} </select> <button type="submit">Submit</button> </form> <hr/> <table border="2" width="100%"> <thead> <tr> {% for column in data.columns %} <th>{{ column }}</th> {% endfor %} </tr> </thead> <tbody> {% for row in data.values %} <tr style="text-align:center"> {% for cell in row %} <td>{{ cell }}</td> {% endfor %} </tr> {% endfor %} </tbody> </table> </body> </html>
解决方案
1. 后端修改:新增价格查询接口
在app.py中添加接口用于根据公司名称返回对应价格,同时优化初始化逻辑:
from flask import Flask, render_template, request, jsonify # 新增jsonify import pandas as pd import sqlalchemy as sal from sqlalchemy import create_engine import pyodbc import urllib import numpy as np app = Flask(__name__) get_data_through = "manual_entry" # 新增:根据公司获取对应价格的接口 @app.route('/get_prices') def get_prices(): company = request.args.get('company') read_df = pd.DataFrame( [ ['Company1', 23, 10000], ['Company2', 22, 40000], ['Company2', 40, 40000] ], columns=['new_sql_table','Open_price', 'volume'] ) # 获取该公司的唯一价格列表 prices = read_df[read_df['new_sql_table'] == company]['Open_price'].unique().tolist() return jsonify(prices) @app.route('/') def index(): read_df = pd.DataFrame( [ ['Company1', 23, 10000], ['Company2', 22, 40000], ['Company2', 40, 40000] ], columns=['new_sql_table','Open_price', 'volume'] ) names = set(read_df['new_sql_table'].tolist()) tickers = request.args.getlist('tickers_get') # 修改:根据选中的公司过滤价格,避免重复选项 if tickers: open_price_to_filter = read_df[read_df['new_sql_table'].isin(tickers)]['Open_price'].unique().tolist() else: open_price_to_filter = read_df['Open_price'].unique().tolist() open_price = request.args.getlist('open_price_get') open_price_get_to_number = ''.join(open_price) if open_price else '' data = read_df[read_df['new_sql_table'].isin(tickers)] sum_of_volumns = format(sum(data['volume']), ',') if not data.empty else '0' return render_template('template.html', **locals()) if __name__ == "__main__": app.run(port = 5050, debug=True) # 开启debug方便调试
2. 前端修改:添加联动逻辑
在template.html的<body>末尾添加JavaScript,监听公司下拉框的变化并动态更新价格选项:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel= "stylesheet" type= "text/css" href= "{{ url_for('static',filename='styles/mainpage.css') }}"> <title>Stocks data</title> </head> <body> <h2>Stocks data</h2><h4>Total Volume is : {{sum_of_volumns}} and selected open price is {{open_price_get_to_number}}</h4> <form> <label>Company:</label> <select name="tickers_get"> {% for name in names %} <option value="{{ name }}" {% if name in tickers %}selected{% endif %}>{{name}}</option> {% endfor %} </select> <label>Open Price:</label> <select name="open_price_get" style="width:75px"> {% for op in open_price_to_filter %} <option value="{{ op }}" {% if op in open_price %}selected{% endif %}>{{op}}</option> {% endfor %} </select> <button type="submit">Submit</button> </form> <hr/> <table border="2" width="100%"> <thead> <tr> {% for column in data.columns %} <th>{{ column }}</th> {% endfor %} </tr> </thead> <tbody> {% for row in data.values %} <tr style="text-align:center"> {% for cell in row %} <td>{{ cell }}</td> {% endfor %} </tr> {% endfor %} </tbody> </table> <!-- 新增:联动逻辑脚本 --> <script> const companySelect = document.querySelector('select[name="tickers_get"]'); const priceSelect = document.querySelector('select[name="open_price_get"]'); // 监听公司选择变化 companySelect.addEventListener('change', async () => { const selectedCompany = companySelect.value; // 调用后端接口获取价格 const res = await fetch(`/get_prices?company=${selectedCompany}`); const prices = await res.json(); // 清空原有选项并添加新选项 priceSelect.innerHTML = ''; prices.forEach(price => { const option = document.createElement('option'); option.value = price; option.textContent = price; priceSelect.appendChild(option); }); }); </script> </body> </html>
内容的提问来源于stack exchange,提问作者navee pp
相关产品推荐
相关产品推荐

