简体   繁体   English

根据之前在 Flask python 中的选择填充下拉菜单,而不使用 ajax?

[英]Populate the drop-down menu based on previous selection in Flask python without using ajax?

I have a csv file in the form of dataframe which consist of location, Device and unit.我有一个 dataframe 形式的 csv 文件,其中包括位置、设备和单元。 Locations may be repeated locations with different units and devices.位置可能是具有不同单元和设备的重复位置。

I want 4 dropdown menu with我想要4个下拉菜单

  • Location地点
  • Unit单元
  • Sub Unit亚基
  • Device设备

And a submit button, which displays all the selected fields.还有一个提交按钮,它显示所有选定的字段。

On selection of location, it should display all unique locations based on the selection of location like PA, select unit will display like在选择位置时,它应该显示所有基于位置选择的唯一位置,如 PA,select 单元将显示如下

Unit

    >:LAN
    >:WAN

Subunit

    >. LAN Switch
    >. WAN switch

Device

    > D2
    > D4

This is a example of the problem statement.这是问题陈述的一个例子。 Original file consist thousand locations and related units.原始文件由数千个位置和相关单元组成。

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

app.py:应用程序.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()

index.html索引.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>

If you want to avoid going through an ajax request then you should consider registering your datas on the client side, by using technologies such as IndexedDB .如果您想避免通过 ajax 请求,那么您应该考虑使用IndexedDB等技术在客户端注册您的数据。

But if you want to keep your information on the server side, and access it dynamically, here's how you can implement that:但是,如果您想将信息保存在服务器端并动态访问它,您可以通过以下方式实现:

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

I create a form that I populate dynamically with the values of the locations only.我创建了一个仅使用位置值动态填充的表单。 then I render the form.然后我渲染表格。

In my JS script I put an event that is triggered whenever there is a change in the field of locations.在我的 JS 脚本中,我放置了一个在位置字段发生变化时触发的事件。

At each change I send the selected value ( location ) to the device_choice route and find all the devices associated with this location.每次更改时,我都会将选定的值 ( location ) 发送到device_choice route并找到与该位置关联的所有设备。 I return the devices as a list and fill in the appropriate selectfield ( devices )我将设备作为列表返回并填写适当的选择字段( devices

HTML's SIDE 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>

You just have to apply the same logic for the units too...您也只需对单位应用相同的逻辑...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM