我接受了一些用户输入,生成了一个表格,我可以 display .现在我想让用户选择一些数据,然后将这些数据发送回另一个函数,在那里进一步处理。对于我用于演示目的的玩具示例,它可能看起来像这样:
不幸的是,我没有这样做。关键部分可能是这个jquery
部分(完整代码可以在下面找到):
$('#send_data').bind('click', function() {
$.getJSON('/_selected_data', {
sel_data: table.rows().data().toArray()
}, function(data) {
alert('This worked')
});
return false;
});
以及我的这部分 Python 代码:
@app.route('/_selected_data')
def get_selected_data():
sel_data = request.args.get('sel_data')
当我打印 sel_data
时,它打印出 None
,当我使用 requests.json
时,它也不起作用;理想情况下,可以将结果作为具有相同列标题的 Pandas 数据框再次获得。
我该如何正确地做到这一点?另外,如果用户没有选择任何数据,那么当然应该返回整个表。
这是完整的代码:
from flask import Flask, render_template, request, jsonify
import pandas as pd
import numpy as np
import json
# just for reproducibility
np.random.seed(0)
# Initialize the Flask application
app = Flask(__name__)
@app.route('/')
def index():
return render_template('index.html')
@app.route('/_get_table')
def get_table():
a = request.args.get('a', type=int)
b = request.args.get('b', type=int)
df = pd.DataFrame(np.random.randint(0, 100, size=(a, b)), columns=['C1', 'C2'])
return jsonify(number_elements=a * b,
my_table=json.loads(df.to_json(orient="split"))["data"],
columns=[{"title": str(col)} for col in json.loads(df.to_json(orient="split"))["columns"]])
@app.route('/_selected_data')
def get_selected_data():
sel_data = request.args.get('sel_data')
print(sel_data)
return jsonify(dummy_data=1)
if __name__ == '__main__':
app.run(debug=True)
和我的index.html
<!DOCTYPE html>
<html lang="en">
<head>
<link href="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdn.datatables.net/1.10.16/css/jquery.dataTables.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
<div class="header">
<h3 class="text-muted">Create a pretty table</h3>
</div>
<div>
<p>Number of rows</p>
<input type="text" size="5" id="a" value="10">
<p>Number of columns</p>
<input type="text" size="5" id="b" value="2">
<p><a href="javascript:void();" id="calculate">get a pretty table</a></p>
<p><a href="javascript:void();" id="send_data">send selected data</a></p>
<p>Result</p>
<p>Number of elements:</p>
<span id="elements">Hallo</span><br>
<table id="a_nice_table" class="table table-striped">Here should be a table</table>
</div>
</div>
<script src="https://code.jquery.com/jquery-1.12.4.js" type="text/javascript"></script>
<script src="https://cdn.datatables.net/1.10.16/js/jquery.dataTables.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function() {
var table = null;
$('#calculate').bind('click', function() {
$.getJSON('/_get_table', {
a: $('#a').val(),
b: $('#b').val()
}, function(data) {
$("#elements").text(data.number_elements);
if (table !== null) {
table.destroy();
table = null;
$("#a_nice_table").empty();
}
table = $("#a_nice_table").DataTable({
data: data.my_table,
columns: data.columns
});
});
return false;
});
$('#send_data').bind('click', function() {
$.getJSON('/_selected_data', {
sel_data: table.rows().data().toArray()
}, function(data) {
alert('This worked')
});
return false;
});
});
</script>
</body>
</html>
最佳答案
这是我尝试解决您的问题的方法。我假设用户一次只能选择一行。
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<link href="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdn.datatables.net/1.10.16/css/jquery.dataTables.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
<div class="header">
<h3 class="text-muted">Create a pretty table</h3>
</div>
<div>
<p>Number of rows</p>
<input type="text" size="5" id="a" value="10">
<p>Number of columns</p>
<input type="text" size="5" id="b" value="2">
<p><a href="javascript:void();" id="calculate">get a pretty table</a></p>
<p><a href="javascript:void();" id="send_data">send selected data</a></p>
<p>Result</p>
<p>Number of elements:</p>
<span id="elements">Hallo</span><br>
<table id="a_nice_table" class="table table-striped">Here should be a table</table>
</div>
</div>
<script src="https://code.jquery.com/jquery-1.12.4.js" type="text/javascript"></script>
<script src="https://cdn.datatables.net/1.10.16/js/jquery.dataTables.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function() {
var table = null;
var selected = null;
$('#calculate').bind('click', function() {
$.getJSON('/_get_table', {
a: $('#a').val(),
b: $('#b').val()
}, function(data) {
$("#elements").text(data.number_elements);
if (table !== null) {
table.destroy();
table = null;
$("#a_nice_table").empty();
}
table = $("#a_nice_table").DataTable({
data: data.my_table,
columns: data.columns
});
var drawn_table = document.getElementById('a_nice_table'),
selected = drawn_table.getElementsByClassName('selected');
drawn_table.onclick = highlight;
function highlight(e) {
if (selected[0]) selected[0].className = '';
e.target.parentNode.className = 'selected';
}
});
return false;
});
$('#send_data').bind('click', function() {
var selected = $("tr.selected").html();
if (selected != null) {
console.log("<thead>" + $("#a_nice_table thead").html() + "</thead><tbody><tr>" + selected + "</tr></tbody>");
$.getJSON('/_selected_data', {
sel_data: "<thead>" + $("#a_nice_table thead").html() + "</thead><tbody><tr>" + selected + "</tr></tbody>"
}, function(data) {
alert('This worked');
});
} else {
console.log($("#a_nice_table").html());
$.getJSON('/_selected_data', {
sel_data: $("#a_nice_table").html()
}, function(data) {
alert('This worked');
});
}
return false;
});
});
</script>
</body>
</html>
app.py
from flask import Flask, render_template, request, jsonify
import pandas as pd
import numpy as np
import json
# just for reproducibility
np.random.seed(0)
# Initialize the Flask application
app = Flask(__name__)
@app.route('/')
def index():
return render_template('index.html')
@app.route('/_get_table')
def get_table():
a = request.args.get('a', type=int)
b = request.args.get('b', type=int)
df = pd.DataFrame(np.random.randint(0, 100, size=(a, b)), columns=['C1', 'C2'])
return jsonify(number_elements=a * b,
my_table=json.loads(df.to_json(orient="split"))["data"],
columns=[{"title": str(col)} for col in json.loads(df.to_json(orient="split"))["columns"]])
@app.route('/_selected_data')
def get_selected_data():
sel_data = request.args.get('sel_data')
df_list = pd.read_html("<table>" + sel_data + "</table>")
df = pd.concat(df_list)
print(df)
return jsonify(dummy_data=1)
if __name__ == '__main__':
app.run(debug=True)
所以基本上发生的事情是,在随机生成表格后,我必须创建几个变量(drawn_table
和 selected
)来跟踪表格及其选择排。截至目前,当一行被选中时没有视觉上的变化,但是如果您想进行任何 CSS 修改以表示何时被选中,则由您决定。当用户确实单击一行时,该行将获得“已选择”的类分配,并且任何其他行都将被取消选择。这是为了让 JQuery 在将行发送回服务器时知道选择了哪一行。
然后在 send_data
链接中,我会找到 tr
(表行)元素,它具有“selected”类(tr.selected
) 并获取此元素内的 html 代码。如果该元素存在,那么我会将 html 连同表头信息作为 JSON 发送到 flask。如果没有 tr.selected
元素,那么 html 代码显然是未定义的,因此代码将运行 block 的 else
部分并发送整个表。
在 app.py 中,我读取了 JSON 值,它是一串 HTML 代码。因为 Pandas 有一个 read_html
方法,我可以将 HTML 字符串传递给创建数据框列表的方法。然后我concat
构成我最终 df
的数据帧列表。
您可以在 Python 的控制台日志 (print(df)
) 中看到数据帧的结果。您还可以在浏览器检查器中看到 html 代码结果,因为我添加了一些 console.log
语句。
关于python - 如何从数据表发送选定的数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49251306/