[英]Saving HandsOnTable data with Flask
我正在尝试使用Flask从HandsOnTable加载和保存数据。 我正在按照以下说明使用ajax加载和保存(检索和发送)数据。 我设法将数据从返回JSON字典的URL加载到表中,但是我还没有弄清楚如何将数据发送到数据库中。
这是javascript相关部分的样子:
Handsontable.Dom.addEvent(save, 'click', function() {
// save all cell's data
ajax('/json/save.json', 'GET', JSON.stringify({data: hot.getData()}), function (res) {
var response = JSON.parse(res.response);
if (response.result === 'ok') {
exampleConsole.innerText = 'Data saved';
}
else {
exampleConsole.innerText = 'Save error';
}
});
});
因此,希望可以从HandsOnTable中获取数据,并将其转换为这种格式的大型JSON表:
{'data' : [[row 1], [row 2],...]}
以下是相关的Flask视图功能:
@app.route('/json/save.json', methods = ['GET', 'POST'])
@login_required
def jsonSave():
data = request.form['data']
#Do stuff to load data into database
return 'ok'
除去无关的部分。 基本上,我的问题是如何使data = request.form['data']
部分成为保存功能的一部分,并将其变成简单的行列表?
顺便说一句,造成这种困难的部分原因是我看不到通过ajax调用发送给视图函数的确切信息。 有没有一种方法可以使我更轻松地调试像这样的问题? 打印语句似乎不适用于视图功能(我无法在控制台中看到它们)。
非常感谢Alex
根据ZekeDroid的指示, 更新 (再次)更改为:
Handsontable.Dom.addEvent(save, 'click', function() {
// save all cell's data
console.log(JSON.stringify({data: hot.getData()}));
ajax('/json/save/{{well['id']}}', 'POST', JSON.stringify({data: hot.getData()}), function (res) {
var response = JSON.parse(res.response);
if (response.result === 'ok') {
exampleConsole.innerText = 'Data saved';
}
else {
exampleConsole.innerText = 'Save error';
}
});
});
和
@app.route('/json/save/<int:well_id>', methods = ['GET', 'POST'])
@login_required
def jsonSave(well_id):
jsonData = request.get_json()
print 'jsonData:', jsonData
data = jsonData['data']
print 'data:', data
#Insert table into database
print 'saving', well_id
return json.dumps(True)
调试输出 :基本上,当Flask调用jsonData = request.get_json()
时,它似乎未加载json对象。 console.log(JSON.stringify({data: hot.getData()}));
看起来还可以。
这是浏览器和Flask控制台的输出:
浏览器:
{"data":[["01/01/15",100,300,200,96],["01/02/15",200,500,300,50],["01/03/15",300,600,400,80],["01/01/15",100,300,200,96],["01/02/15",200,500,300,50],["01/03/15",300,600,400,80],["01/01/15",100,300,200,96],["01/02/15",200,500,300,50],["01/03/15",300,600,400,80],[null,null,null,null,null]]}
samples.js:94 POST http://127.0.0.1:5000/json/save/1 500 (INTERNAL SERVER ERROR)
烧瓶:
jsonData: None
127.0.0.1 - - [13/May/2015 11:41:31] "POST /json/save/1 HTTP/1.1" 500 -
Traceback (most recent call last):
File "C:\Users\aschmitt\Envs\PetroTools\lib\site-packages\flask\app.py", line
1836, in __call__
return self.wsgi_app(environ, start_response)
File "C:\Users\aschmitt\Envs\PetroTools\lib\site-packages\flask\app.py", line
1820, in wsgi_app
response = self.make_response(self.handle_exception(e))
File "C:\Users\aschmitt\Envs\PetroTools\lib\site-packages\flask\app.py", line
1403, in handle_exception
reraise(exc_type, exc_value, tb)
File "C:\Users\aschmitt\Envs\PetroTools\lib\site-packages\flask\app.py", line
1817, in wsgi_app
response = self.full_dispatch_request()
File "C:\Users\aschmitt\Envs\PetroTools\lib\site-packages\flask\app.py", line
1477, in full_dispatch_request
rv = self.handle_user_exception(e)
File "C:\Users\aschmitt\Envs\PetroTools\lib\site-packages\flask\app.py", line
1381, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "C:\Users\aschmitt\Envs\PetroTools\lib\site-packages\flask\app.py", line
1475, in full_dispatch_request
rv = self.dispatch_request()
File "C:\Users\aschmitt\Envs\PetroTools\lib\site-packages\flask\app.py", line
1461, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "C:\Users\aschmitt\Envs\PetroTools\lib\site-packages\flask_login.py", lin
e 758, in decorated_view
return func(*args, **kwargs)
File "C:\Users\aschmitt\Dropbox\Python\PetroTools\app\views.py", line 236, in
jsonSave
data = jsonData['data']
TypeError: 'NoneType' object has no attribute '__getitem__'
到目前为止,这是一个很好的问题,也是一项出色的工作! 现在,让我们从显而易见的内容开始。 您正在使用GET
请求向Flask发送数据,但实际上是在尝试POST
数据,这就是为什么Python在request
什么都没有的原因。 如果我错了,请纠正我,因为可能不是这种情况,但是这是调试方法:
您应该在某个地方的外壳上运行烧瓶。 在这里,您将看到所有print
语句,因此,在定义它之后,在jsonSave()
添加行print data
。 另外,由于两个原因,您错误地检索了数据。 首先,语法如下:
jsonData = request.get_json()
data = jsonData["data"]
另外,如果您期望状态响应,那么使用JSON和一个布尔值来响应可能是值得的:
return json.dumps(True)
现在是前端。 在将数据发送到服务器之前,只需将其打印到控制台即可。 在ajax
调用的上方添加以下行:
console.log(JSON.stringify({data: hot.getData()}));
这足以调试双方。 看到并进行更改后,我建议您应该对什么地方出了问题有一个更好的了解,但是如果没有,请使用您认为相关的输出来更新您的问题(例如,如果python在尝试打印data
时正在打印一个空行) )。
编辑:
无法以您设置路线的方式接收参数是不正确的。 还有为什么你有save.json
? 相反,请尝试以下操作:
@app.route('/json/save/<well_id>', methods = ['GET', 'POST'])
@login_required
def jsonSave(well_id):
jsonData = request.get_json()
data = jsonData['data'] # this will fail if it is not a POST request
print 'data:', data
#Do stuff to load data into Database
print 'saving', well_id
return json.dumps(True)
在您的ajax调用中:
ajax('/json/save/{{well['id']}}', 'POST', JSON.stringify({data: hot.getData()}), function (res) {})
另外,请发布控制台日志和打印语句。 我们仍然在黑暗中。
为了解决这个问题,我从头开始。 我包括了以下JavaScript文件:
<script src="https://code.jquery.com/jquery-1.11.1.min.js"></script>
<link rel="stylesheet" media="screen" href="http://handsontable.com/dist/handsontable.full.css">
<script src="http://handsontable.com/dist/handsontable.full.js"></script>
我删除了从旧jsfiddle获得的samples.js
文件。 我认为这很混乱。
根据ZekeDroid的建议,我将烧瓶保存功能更改为:
@app.route('/json/save/<int:well_id>', methods = ['GET', 'POST'])
@login_required
def jsonSave(well_id):
w = Well.query.get(well_id)
jsonData = request.get_json()
print 'jsonData:', jsonData
data = jsonData['data']
print 'data:', data
#Load Data dictionary into the database.
return json.dumps(True)
我用以下命令替换了jQuery保存功能:
Handsontable.Dom.addEvent(save, 'click', function() {
// save all cell's data
var arr = { data: hot.getData()};
$.ajax({
url: '/json/save/{{well['id']}}',
type: 'POST',
data: JSON.stringify(arr),
contentType: 'application/json; charset=utf-8',
dataType: 'json',
async: true,
success: function(msg) {
console.log(msg);
}
});
});
我无法从动手教程( 此处 )获得保存功能,因此我在这里使用了可接受的答案。 我使用POST是因为,如果我理解正确,它没有GET那样的大小限制,并且我将要发送一些非常大的数组。
删除samples.js
文件也破坏了加载功能,因此我将其替换为:
Handsontable.Dom.addEvent(load, 'click', function() {
var arr = { data: []};
$.ajax({
url: '/json/load/{{well['id']}}',
type: 'GET',
contentType: 'application/json; charset=utf-8',
data: JSON.stringify(arr),
dataType: 'json',
async: true,
success: function(msg) {
hot.loadData(msg.data);
console.log('Loaded:');
console.log(msg.data);
}
});
});
这显然与保存功能非常相似。 感谢您提供的所有帮助ZekeDroid。
亚历克斯
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.