无法搜索任何内容
我一直在尝试实现一个从数据库表中搜索用户的函数,但一直在修复中。
我尝试按照教程来做,但没有成功,也找不到使用Python Flask + SQLite的解决方案。
我希望搜索栏在数据库中基于我输入的一个字母(用于更广泛的搜索)或用户的完整姓名或邮箱来搜索用户。我想直接搜索到某个用户,并能够对其进行修改(如更改其角色)或删除该用户。
response.html
<h3>{{numrows}} Records Found</h3>
<table class="table table-striped custab">
<thead>
<tr>
<th>ID</th>
<th>Naam</th>
<th>E-mail</th>
<th>Huidige rol</th>
<th>Nieuwe rol</th>
<th>Actie</th>
</tr>
</thead>
<tbody>
{% for row in user %}
<tr>
<tr>
<td>{{ row.id }}</td>
<td>{{ row.name }}</td>
<td>{{ row.email }}</td>
<td>
{% if row.role_id == 1 %}
<span class="role-student">Student</span>
{% elif row.role_id == 2 %}
<span class="role-teacher">Docent</span>
{% elif row.role_id == 3 %}
<span class="role-admin">Admin</span>
{% endif %}
</td>
<td>
<form method="POST" action="{{ url_for('update_user_role') }}" style="display: inline;">
<input type="hidden" name="user_id" value="{{ user.id }}">
<label>
<select name="role_id" class="role-select">
<option value="1" {% if user.role_id == 1 %}selected{% endif %}>Student</option>
<option value="2" {% if user.role_id == 2 %}selected{% endif %}>Docent</option>
<option value="3" {% if user.role_id == 3 %}selected{% endif %}>Admin</option>
</select>
<button type="submit" class="btn-update">Update</button>
</label>
</form>
</td>
<td>
<form method="POST" action="{{ url_for('delete_user') }}" name="delete-user" onsubmit=" return confirm('Bent u zeker u wilt dit account verwijderen')"> <!-- Confirm of u wilt een account verwijderen-->
<input type="hidden" name="user_id" value="{{ user.id }}">
<button type="submit" class="btn-delete">Delete</button>
</form>
</td>
</tr>
{% endfor %}
</tbody>
</table>
在一个独立的script.js文件,名为admin.js
load_data();
function load_data(query)
{
$.ajax({
url:"/ajaxlivesearch",
method:"POST",
data:{query:query},
success:function(data)
{
$('#result').html(data);
$("#result").append(data.htmlresponse);
}
});
}
$('#searchUsers').keyup(function(){
var search = $(this).val();
if(search != ''){
load_data(search);
}else{
load_data();
}
});
<div class="container search-table">
<p><h2 align="center">Gebruikers zoeken</h2></p>
<div class="search-box">
<div class="row">
<div class="col-md-3">
<h5>Search All Fields</h5>
</div>
<div class="col-md-9">
<input type="text" name="search_text" id="searchUsers" class="form-control" placeholder="Zoek op naam of e-mail...">
</div>
</div>
</div>
<div id="result"></div>
</div>
这部分应该放在app.py中,数据库处理在单独的模型中(app.py)
@app.route("/ajaxlivesearch",methods=["POST","GET"])
def ajaxlivesearch():
conn = get_db_connection()
if request.method == 'POST':
search_word = request.form['query']
print(search_word)
if search_word == '':
query = "SELECT * from users ORDER BY id"
conn.execute(query)
user = conn.fetchall()
else:
query = "SELECT * from users WHERE name LIKE '%{}%' OR email LIKE '%{}%' ORDER BY id DESC LIMIT 20".format(search_word,search_word)
conn.execute(query)
numrows = int(conn.rowcount)
user = conn.fetchall()
print(numrows)
return jsonify({'htmlresponse': render_template('response.html', user=user, numrows=numrows)})
解决方案
我尝试运行代码,首先的问题是 load_data(); 对参数 query 没有值,因此会把它当作 undefined,你试图发送 data:{query:undefined},但 ajax() 会跳过 data:{query:undefined},服务器因此会因为表单没有键名 query 而抛出关于 request.form['query'] 的错误。
你需要使用下列方法之一:
- 在所有位置将其作为空字符串
load_data('');(在所有地方) - 使用
||将undefined替换为空字符串,等同于or的做法 - 比如data:{query:query||''} - 在Python中,当
request.form中不存在query时,使用form.get('query, '')以获得空字符串
另一个问题可能与 numrows 有关:你在 search_word == '' 时没有创建它,但后来你有 render_template(..., numrows=numrows),这应该会触发错误。
这两个问题都应该在Python中抛出错误,你应该在控制台看到它们。它们会向你展示代码哪里出错。你应该把错误信息放在问题里。
另一个想法:也许问题出在你使用数据库的方式。
如果你没有 conn.row_factory = sqlite3.Row,那么它可能需要 row[0] 而不是 row.id,等等。这可能会在表中产生空值。
带有示例数据的完整可运行代码(它需要执行 create_database() insert_example_data())以及在代码中直接包含HTML的版本(使用 render_template_string),这样每个人都可以直接复制并运行。
import sqlite3
from flask import Flask, request, jsonify, render_template, render_template_string
app = Flask(__name__)
def create_database():
conn = sqlite3.connect("data.sqlite")
cur = conn.cursor()
cur.execute(
"""
DROP TABLE IF EXISTS users;
"""
)
cur.execute(
"""
CREATE TABLE users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
email TEXT NOT NULL UNIQUE,
role_id INTEGER NOT NULL
);
"""
)
conn.commit()
conn.close()
print("Database created.")
def insert_example_data():
conn = sqlite3.connect("data.sqlite")
cur = conn.cursor()
users = [
("Alice Johnson", "[email protected]", 1),
("Bob Smith", "[email protected]", 2),
("Charlie Brown", "[email protected]", 3),
("David Miller", "[email protected]", 1),
("Eva Green", "[email protected]", 2),
("Frank Underwood", "[email protected]", 3),
("Grace Hopper", "[email protected]", 2),
("Hannah Lee", "[email protected]", 1),
]
cur.executemany(
"""
INSERT INTO users (name, email, role_id)
VALUES (?, ?, ?)
""",
users,
)
conn.commit()
conn.close()
print("Seed data inserted.")
def get_db_connection():
conn = sqlite3.connect("data.sqlite")
conn.row_factory = sqlite3.Row
cur = conn.cursor()
return cur
@app.route("/")
def index():
return """
<div class="container search-table">
<p><h2 align="center">Gebruikers zoeken</h2></p>
<div class="search-box">
<div class="row">
<div class="col-md-3">
<h5>Search All Fields</h5>
</div>
<div class="col-md-9">
<input type="text" name="search_text" id="searchUsers" class="form-control" placeholder="Zoek op naam of e-mail...">
</div>
</div>
</div>
<div id="result"></div>
</div>
<script
src="https://code.jquery.com/jquery-4.0.0.min.js"
integrity="sha256-OaVG6prZf4v69dPg6PhVattBXkcOWQB62pdZ3ORyrao="
crossorigin="anonymous"></script>
<script>
load_data();
function load_data(query)
{
console.log({query:query});
$.ajax({
url:"/ajaxlivesearch",
method:"POST",
data:{query:query||""},
success:function(data)
{
$('#result').html(data.htmlresponse);
//$("#result").append(data.htmlresponse);
}
});
}
$('#searchUsers').keyup(function(){
var search = $(this).val();
if(search != ''){
load_data(search);
}else{
load_data();
}
});
</script>
"""
response_html = """<h3>{{numrows}} Records Found</h3>
<table class="table table-striped custab">
<thead>
<tr>
<th>ID</th>
<th>Naam</th>
<th>E-mail</th>
<th>Huidige rol</th>
<th>Nieuwe rol</th>
<th>Actie</th>
</tr>
</thead>
<tbody>
{% for row in user %}
<tr>
<td>{{ row.id }}</td>
<td>{{ row.name }}</td>
<td>{{ row.email }}</td>
<td>
{% if row.role_id == 1 %}
<span class="role-student">Student</span>
{% elif row.role_id == 2 %}
<span class="role-teacher">Docent</span>
{% elif row.role_id == 3 %}
<span class="role-admin">Admin</span>
{% endif %}
</td>
<td>
<form method="POST" action="{{ url_for('update_user_role') }}" style="display: inline;">
<input type="hidden" name="user_id" value="{{ row.id }}">
<label>
<select name="role_id" class="role-select">
<option value="1" {% if user.role_id == 1 %}selected{% endif %}>Student</option>
<option value="2" {% if user.role_id == 2 %}selected{% endif %}>Docent</option>
<option value="3" {% if user.role_id == 3 %}selected{% endif %}>Admin</option>
</select>
<button type="submit" class="btn-update">Update</button>
</label>
</form>
</td>
<td>
<form method="POST" action="{{ url_for('delete_user') }}" style="display: inline;" name="delete-user"
onsubmit="return confirm('Bent u zeker u wilt dit account verwijderen')">
<input type="hidden" name="user_id" value="{{ row.id }}">
<button type="submit" class="btn-delete">Delete</button>
</form>
</td>
</tr>
{% endfor %}
</tbody>
</table>"""
@app.route("/ajaxlivesearch", methods=["POST", "GET"])
def ajaxlivesearch():
conn = get_db_connection()
user = "" # default value for `GET`
numrows = 0 # default value for `GET`
if request.method == "POST":
search_word = request.form.get("query", "")
print(f"{search_word=}")
if search_word == "":
query = "SELECT * from users ORDER BY id"
conn.execute(query)
else:
query = "SELECT * from users WHERE name LIKE ? OR email LIKE ? ORDER BY id DESC LIMIT 20"
conn.execute(query, (f"%{search_word}%", f"%{search_word}%"))
user = conn.fetchall()
numrows = conn.rowcount
numrows = len(user)
print(f"{numrows=}")
print(user)
# return jsonify({"htmlresponse": render_template("response.html", user=user, numrows=numrows)})
return jsonify(
{
"htmlresponse": render_template_string(
response_html, user=user, numrows=numrows
)
}
)
@app.route("/update", methods=["POST"])
def update_user_role():
return "[NOT IMPLEMENTED]"
@app.route("/delete", methods=["POST"])
def delete_user():
return "[NOT IMPLEMENTED]"
if __name__ == "__main__":
# create_database()
# insert_example_data()
app.debug = True
app.run()

