我是一名学习 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
)
根据我的评论,您的代码似乎介于两种请求样式之间: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)