簡體   English   中英

如何使用 Flask 從 html select 標簽中獲取選定的值

[英]How to get the selected value from html select tag using Flask

我知道以前有人問過這個問題,但我已經瀏覽了所有帖子,但似乎沒有一個解決方案對我有用。

請多多包涵。 我是 Flask 和 html 的新手,正在嘗試構建我的第一個 Web 應用程序。

它應該按如下方式工作:用戶上傳 Excel 工作簿,工作簿標題使用 html“選擇”標簽顯示在下拉列表中。 然后用戶應該選擇標題之一。 然后我想將選定的標題傳遞給一個函數。

我可以在下拉列表中顯示工作簿標題,但是當我選擇一個標題時,沒有任何反應。 有誰知道我做錯了什么?

請看下面的python代碼:

import flask
from flask import Flask
from flask import request
import pandas as pd

app = Flask(__name__)

@app.route("/", methods=["GET", "POST"])
def index():
    global headers_list
    headers_list=[]

    if request.method == "POST":
        df=request.files["file"]
        if df:
            df=pd.read_excel(df)
            headers_list=get_headers(df)
            selected_header = request.form.get("header")
            print(str(selected_header)) #to test the code
        else:
            print("No file selected")
    return (flask.render_template("./index.html", headers_list=headers_list))

def get_headers(dataframe):
    headers=list(dataframe.columns)
    return headers

if __name__ == "__main__":
    app.run(host="127.0.0.1", port=8080, debug=True)

下面的 HTML:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <meta name="description" content=""
        <title><Contra Tool</title>
        
    </head>

    <body>
        <h1>Contra Tool</h1>
        <p>Describe functionality</p>
        <br/>
    </body>

    <form action="" method="post" enctype=multipart/form-data>
        <label for ="myfile" > Select a file:</label>
        <input type="file" id="myfile" name="file" EnableViewState=True>
        <input type="submit" value="Upload">

    </form>

    <br><br>
    
    <div class="dropdown">
    <button class="dropbtn">Dropdown</button>
        <div>
            <form action="" method="POST">
                <SELECT class="dropdown-content" name="header" method="POST" action="/">
                    <ul>
                        <option value="{{headers_list[0]}}" selected>{{headers_list[0]}}</option>
                        {% for h in headers_list[1:]%}
                            <option value="{{h}}">{{h}}</option>
                        {% endfor %}
                    </ul>
                </SELECT>

            </form>

        </div>
    </div>
    
    <br/>
    <input type="submit">

</html>

由於我假設您不想將 excel 文件保存在服務器上,因此我認為仍然存在文件傳輸兩次的變體。
如果用戶選擇一個文件,它會在后台傳輸以查詢標題列。 select 元素填充有接收到的信息。
從現在開始可以選擇一個列並可以傳輸表格。

在我的例子中有兩條路線。 一個用於顯示和處理表單,另一個根據請求以 JSON 格式返回標題列。

from flask import Flask 
from flask import abort, jsonify, render_template, request
import pandas as pd

app = Flask(__name__)

@app.route('/', methods=['GET', 'POST'])
def upload():
    if request.method == 'POST' and 'file' in request.files:
        file = request.files['file']
        df = pd.read_excel(file)
        head = request.form.get('head');
        print(f'selected "{head}"')
    return render_template('index.html')

@app.route('/headers', methods=['POST'])
def headers():
    if 'file' in request.files:
        file = request.files['file']
        df = pd.read_excel(file)
        headers = list(df.columns)
        return jsonify(headers=headers)
    abort(400)

如果用戶選擇了一個文件,它會通過 AJAX 發送到第二個路由。 在收到來自服務器的響應后,select 元素被清空並重新填充,並且所有必要的其他元素都可用。 如果用戶按下提交,完成的表單將與文件和選定的列一起發送。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title></title>
  </head>
  <body>
    <form method="POST" enctype="multipart/form-data">
      <input type="file" name="file" id="file" />
      <select name="head" id="head" disabled>
        <option>Choose Header</option>
      </select>
      <input type="submit" id="submit" disabled />
    </form>

    <script type="text/javascript">
      (() => {
        const fileElem = document.getElementById('file');
        fileElem.addEventListener('change', evt => {
          const formData = new FormData();
          formData.append('file', evt.target.files[0]);
          fetch('/headers', { method: 'POST', body: formData })
            .then(resp => resp.json())
            .then(data => {
              // clear select options
              const selectElem = document.getElementById('head');
              for (let i=selectElem.options.length-1; i >= 0; --i) {
                  selectElem.remove(i);
              }

              // populate select options
              const headers = data['headers'];
              for (const head of headers) {
                const optElem = document.createElement('option');
                optElem.value = head;
                optElem.innerHTML = head;
                selectElem.append(optElem);
              }
              selectElem.disabled = false;

              const elem = document.getElementById('submit');
              elem.disabled = false;
            });
        });
      })();
    </script>
  </body>
</html>

請記住,這是一個最小的示例,可能需要進行調整和修改以滿足您的要求。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM