Flask KeyError 或返回 None

问题描述 投票:0回答:1

我是一名学习 python Flask Web 开发的初学者。我目前正在将程序迁移到网络空间,但遇到了问题。

我的问题是,当您单击“检查价格”按钮时,该按钮应该消失,获取输入字段值并且将出现微调器块,如 js 脚本块中所示。但是,如果单击该按钮,则会出现错误,指出尚未找到“用户输入字段”,尽管该链接同时位于表单和输入字段中。如果在表单中添加id='user-input-field',则执行启动,但js块不起作用(不显示spinner块),并且从输入字段返回None,这是合乎逻辑的。如果更改了表单的 id 名称,则会再次出现 KeyError。可能是什么问题

我的 HTML:

{% extends 'base.html' %}

{% block content %}
<div class="container">
  <div class="row justify-content-center mt-5">
    <div class="col-md-6">
      <div class="card">
        <div class="card-header">
          <h1 class="text-center">Title</h1>
        </div>
        <div class="card-body">
          {% with messages = get_flashed_messages() %}
          {% if messages %}
          <div class="alert alert-danger">
            <ul>
              {% for message in messages %}
              <li>{{ message }}</li>
              {% endfor %}
            </ul>
          </div>
          {% endif %}
          {% endwith %}          
          <form method="post" action="/competitive_list">
            <div class="mb-3">
              <label for="user-input-field" class="form-label">Product name:</label>
              <input type="text" class="form-control" id="user-input-field" name="user-input-field" placeholder="Enter product name" required>
            </div>
            {% if button %}
            <div id="button_container" class="text-center">
              <button type="submit" class="btn btn-primary" onclick="hideFunction()">Check price</button>
            </div>
            {% endif %}
          </form>
          <div class="text-center" id="spinner-block" style="display: none;">
            <p>Searching, please wait ...</p>
            <div class="spinner-border text-success text-align: center" role="status" style="text-align: center"></div>
          </div>          
        </div>
      </div>
      <br>
    </div>
  </div>      
  <script type="text/javascript">

    const hideFunction = () => {        
      const textInputField = document.getElementById('user-input-field');
      const buttonContainer = document.getElementById('button_container');
      const spinnerContainer = document.getElementById('spinner-block');
      console.log(textInputField);

      if (textInputField.value.trim() !== '') {
        buttonContainer.style.display = 'none';
        spinnerContainer.style.display = 'block';
        textInputField.disabled = true;
      } else {
        buttonContainer.style.display = 'block';
        spinnerContainer.style.display = 'none';
      }
    }

  </script>
</div>
{% endblock %}

和 py 文件:

app = Flask(__name__)


@app.route('/competitive_list', methods=["GET", "POST"])
def competitive_list():
    if request.method == 'POST':            
        user_input_name = request.form.get('user-input-field')
        print(user_input_name)        
        time.sleep(2)            
        return render_template('competitive_list.html',                               
                               sample=d,
                               table=True,
                               button=True
                               )
    else:        
        return render_template('competitive_list.html',
                               button=True
                               )
python python-3.x flask keyerror
1个回答
0
投票

根据我的评论,您的代码似乎介于两种请求样式之间:JS 驱动的 AJAX 请求(无需重新加载)和服务器驱动的表单提交(需要重新加载)。

大多数使用旋转器的搜索都涉及前一个选项。 这个答案涵盖了两者,但使用了 jQuery,所以这里有一个最小的普通版本,您可以调整和改进以匹配您的用例。

templates/index.html

<!DOCTYPE html>
<html>
<body>
<form>
  <label for="user-input" class="form-label">Product name:</label>
  <input
    id="user-input"
    name="user-input"
    placeholder="Enter product name"
    required
  />
  <button type="submit">Check price</button>
</form>
<div id="spinner-block" style="display: none">
  <p>Searching, please wait ...</p>
</div>
<ul id="results"></ul>
<script>
  const spinner = document.querySelector("#spinner-block");
  document.querySelector("form").addEventListener("submit", (event) => {
    event.preventDefault();
    const { elements } = event.target;
    const userInput = elements["user-input"].value;
    spinner.style.display = "block";

    fetch("/search", {
      method: "POST",
      headers: {
        Accept: "application/json",
        "Content-Type": "application/json",
      },
      body: JSON.stringify({ userInput }),
    })
      .then((response) => {
        if (!response.ok) {
          throw Error(response.statusText);
        }

        return response.json();
      })
      .then((data) => {
        const results = document.querySelector("#results");
        results.innerHTML = "";

        for (const item of data) {
          const li = document.createElement("li");
          results.appendChild(li);
          li.textContent = `${item.name} - ${item.price}`;
        }
      })
      .catch((err) => console.error(err))
      .finally(() => {
        spinner.style.display = "none";
      });
  });
</script>
</body>
</html>

app.py

from random import randint

from flask import Flask, render_template, request


app = Flask(__name__)


def random_name():
    return "".join([chr(randint(97, 122)) for _ in range(randint(5, 15))])


sample_items = [
    {"name": random_name(), "price": randint(1, 100)}
    for _ in range(300)
]


@app.post("/search")
def search():
    user_input = request.json["userInput"]
    return [x for x in sample_items if user_input in x["name"]]


@app.get("/")
def index():
    return render_template("index.html")


if __name__ == "__main__":
    app.run(host="127.0.0.1", port=8080, debug=True)
© www.soinside.com 2019 - 2024. All rights reserved.