2015-05-04 37 views
2

我試圖使用Flask加載和保存來自HandsOnTable的數據。我遵循these instructions用於使用ajax加載和保存(檢索和發送)數據。我已經設法從返回JSON字典的URL中將數據加載到表中,但我還沒有弄清楚如何發送數據存儲在我的數據庫中。使用Flask保存HandsOnTable數據

這裏是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],...]} 

而且這裏是有關瓶視圖功能是什麼樣子:

@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' 

w ^刪除不相關的部分。基本上我的問題是我如何使data = request.form['data']保存功能的一部分工作,並將其變成一個簡單的行列表?

順便說一句,爲什麼這很困難的一部分是,我不明白是什麼正在發送到視圖函數與ajax調用。有沒有一種方法可以看到,所以我可以更輕鬆地調試這樣的問題?打印語句似乎不能在視圖函數中工作(我無法在控制檯中看到它們)。

非常感謝,亞歷克斯

更新每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) 

調試輸出: 基本上,它看起來像瓶沒有加載一個JSON對象時,它調用jsonData = request.get_json()。但是,console.log(JSON.stringify({data: hot.getData()}));看起來不錯。

下面是瀏覽器和遊戲機瓶輸出:

瀏覽器:

{"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__' 

回答

1

爲了解決這個問題,我開始了。我包括這些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> 

我刪除了samples.js文件,我從老的jsfiddle了。我認爲這是搞砸了。

按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); 
     } 
     }); 
}); 

我無法得到保存功能,從(here)的工作,所以我用接受的答案here來代替。我使用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的所有幫助。

Alex

3

這是一個很好的問題,到目前爲止,偉大的工作!現在,讓我們從明顯的開始。您使用GET請求向Flask發送數據,但實際上您正在嘗試POST數據,這就是爲什麼Python在request中沒有任何內容的原因。糾正我,如果我錯了,因爲這可能不是這種情況,但這裏是你如何調試它:

你應該在一個shell的某處運行瓶。在這裏您將看到任何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 )。

編輯:

爲了能夠接收參數你設置你的路線的方式是不正確的。你爲什麼還有​​3210?相反,試試這個:

@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) {}) 

另外,請請張貼控制檯日誌和報表打印。我們仍然在黑暗中。

+0

非常感謝。我做了你的改變,但我仍然做錯了什麼。當我第一次加載頁面時,它給了我兩個錯誤,'GET http://127.0.0.1:5000/index.html 404(NOT FOUND)'和'Uncaught TypeError:無法讀取'null'屬性'querySelectorAll'。當我嘗試保存數據時,它說'GET http://127.0.0.1:5000/json/save.json/1 500(INTERNAL SERVER ERROR)'和'Uncaught SyntaxError:Unexpected token <'。這可能與樣品有關嗎?我從舊版本的HandsOnTable網站複製的js文件,因爲它不再被託管在那裏? –

+0

我正在使用[this jsFiddle](http://jsfiddle.net/api/post/library/pure/)作爲參考,您可以在其中看到它包含''。該文件已不存在,但我從回機器獲得了一個歸檔版本並使用了該文件。不確定這是否會成爲一些問題的根源? –

+0

好的,讓我們來看看。首先,從更新的問題,你做了兩件事情是錯誤的。一個是你的ajax調用仍在執行GET請求,所以第三個參數被忽略,第二,在你的Flask代碼中,你實際上沒有獲得任何參數,請參閱我的更新響應。 – ZekeDroid