首页 > 解决方案 > 在不使用 ajax 的情况下,根据之前在 Flask python 中的选择填充下拉菜单?

问题描述

我有一个数据框形式的 csv 文件,它由位置、设备和单元组成。位置可能是具有不同单元和设备的重复位置。

我想要4个下拉菜单

还有一个提交按钮,它显示所有选定的字段。

在选择位置时,它应该显示所有基于位置选择的唯一位置,如 PA,选择单元将显示为

Unit

    >:LAN
    >:WAN

Subunit

    >. LAN Switch
    >. WAN switch

Device

    > D2
    > D4

这是问题陈述的一个例子。原始文件由数千个位置和相关单元组成。

> Location   Device  Unit
> USA         D1     LAN core
> PA          D2     LAN Switch
> BLR         D3     LAN core
> PA          D4     WAN switch
> MEL         D5     DC metro

应用程序.py:

from flask import Flask, render_template, request
    import pandas as pd
    app = Flask(__name__)
    app.debug = True

    @app.route('/', methods=['GET'])
    def dropdown():
        total_data = pd.read_csv("CPS.csv")
        print(total_data)
        data = total_data['LOCATION'].unique()
        print(data)

        return render_template('index.html', data=data)

    if __name__ == "__main__":
        app.run()

索引.html

<!DOCTYPE html>
  <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>Dropdown</title>
    </head>
    <body>
      <select name= data  method="GET" action="/">
        {% for row in data %}
        <option value= "{{row}}" SELECTED>{{row}}</option>"
        {% endfor %}
      </select>
    </body>
  </html>

标签: pythonhtmlflaskweb-applicationsdrop-down-menu

解决方案


如果您想避免通过 ajax 请求,那么您应该考虑使用IndexedDB等技术在客户端注册您的数据。

但是,如果您想将信息保存在服务器端并动态访问它,您可以通过以下方式实现:

from flask_wtf import FlaskForm
from wtforms import SelectField
from flask import Flask, render_template, request, jsonify
import pandas as pd

class LocationsForm(FlaskForm):
    locations = SelectField('Locations')

@app.route('/', methods=['GET', 'POST'])
def dropdown():
    total_data = pd.read_csv("CPS.csv")
    data = total_data['LOCATION'].unique().tolist()

    form = LocationsForm()
    form.locations.choices = [(i, i) for i in data]

    return render_template(form=form)


@app.route('/device_choice/<value>')
def device_choice(value):
    location_choosen = value
    df = pd.read_csv("CPS.csv")
    df = df.set_index(["LOCATION"])
    df1 = df.loc[location_choosen, 'Device'].tolist()

    return jsonify({'Devices': df1})

@app.route('/unit_choice/<value>')
def unit_choice(value):
    # YOU CAN IMPLEMENT THIS BY FOLLOWING THE SAME MODEL AS THE DEVICES

我创建了一个仅使用位置值动态填充的表单。然后我渲染表格。

在我的 JS 脚本中,我放置了一个在位置字段发生变化时触发的事件。

每次更改时,我都会将选定的值 ( location) 发送到device_choice route并查找与该位置关联的所有设备。我将设备作为列表返回并填写适当的选择字段 ( devices)

HTML的侧面

<!DOCTYPE html>
  <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>Dropdown</title>
    </head>
    <body>
      {{ form.hidden_tag() }}
      {{ form.locations(class_="form-control") }}
      <select class="form-control devices" id="devices"></select>
      <select class="form-control unit" id="unit"></select>
    </body>
    <script>
        let location = document.getElementById('locations');
        let devices = document.getElementById('devices');

        location.onchange = function(){
            value = location.value;

            fetch('/device_choice/' + value).then(function(response){

                response.json().then(function(data){
                    let optionHTML = '';

                    for(let opt of data.Devices){
                        optionHTML += '<option value ="'  + opt + '">' + opt + '</option>';
                    }

                    devices.innerHTML = optionHTML;

                });
            });
        }
  </script>
  </html>

您也只需对单位应用相同的逻辑...


推荐阅读