2012-08-30 69 views
5

我是Backbone.js的新手,我試圖保存一個模型實例。 我使用django作爲我的服務器。保存Backbone.js模型數據。數據發送不正確

客戶端代碼:

var Song = Backbone.Model.extend({ 
    defaults: { 
     name: 'New Song' 
    }, 
    url: function() { 
     return window.location.href; 
    } 

}); 

var song = new Song() 
song.save() 

csrfmiddlewaretoken設置正確發送數據之前。

我穿過了由 Backbone.sync在內部調用的jQuery $ .ajax函數,發現模型對象包含正確的數據。

然而,由服務器接收的request.POST

POST:<QueryDict: {u'[object Object]': [u'']}> 

而不是實際數據。任何想法,我要去哪裏錯了?

更新:我做了一個快速修復,將Backbone.emulateJSON設置爲true。但根據Backbone(0.9.2)代碼中的意見,它指的是傳統服務器。我正在使用Django 1.4.1。這是否意味着django 1.4.1不兼容?

更新2:當我設置Backbone.emulateJSONfalse,我得到在Firefox下面的錯誤,但它在悄悄鉻失敗。

"[Exception... "Component returned failure code: 0x80460001 
(NS_ERROR_CANNOT_CONVERT_DATA)" nsresult: "0x80460001 (NS_ERROR_CANNOT_CONVERT_DATA)" 

    location: "JS frame :: http://localhost:8000/static/jquery.js :: <TOP_LEVEL> :: line 8214" data: no]" 

我使用jQuery阿賈克斯由骨幹作爲首選,它似乎錯誤可能是jQuery的。

更新3:我解決了它,通過重寫由我自己的Backbone.sync使用的$ .ajax。這仍然是一個快速解決方案。

Backbone.js verson:0.9.2

jQuery version:1.8.0。也試過1.7.2。同樣的結果。

+0

您可以查看您的網絡面板並查看發佈到您的服務器的數據。我對Django並不熟悉,但是您的問題看起來像是服務器端問題,而不是Backbone問題。 – TYRONEMICHAEL

+0

@TyroneMichael感謝您的建議。 chrome中的網絡面板顯示該模型是作爲Request Payload中的普通對象發送的。但在Firefox中,我得到了更新2中寫入的錯誤。 – Pramod

+0

我不認爲數據是以字符串形式發送的(請看[這裏](http://communities.rightnow.com/posts/9580c78607))。 Emulate JSON爲false時會出現此錯誤嗎?當你評論Emulate JSON = false時,在FF中會發生什麼? – TYRONEMICHAEL

回答

9

我有一個類似的問題,並通過一些偵探工作/運氣我想通了。問題在於,默認情況下,Backbone將POST數據作爲請求正文中的JSON編碼字符串發送,而不是Query Query的request.POST的一部分。因此,爲了在這種情況下獲取數據,您必須使用python json庫並在Django視圖中調用json.loads(request.body)以正確讀取數據。

另外,設置Backbone.emulateJSON = true;工作的原因是因爲Backbone通過「遺留」機制將JSON發送給Django,使其出現在QueryDict的request.POST中。

+0

...或者'json.loads(request.raw_post_data)'爲老版本的django –

1

如果您希望數據在QueryDict request.POST中可用,那麼您將不得不重寫Backbone.sync方法。

首先,您將不得不將Backbone.emulateJSON設置爲true。

您可以通過here查看Backbone.sync方法。您會注意到模型屬性已被字符串化。

if (options.data == null && model && (method === 'create' || method === 'update' || method === 'patch')) { 
    params.contentType = 'application/json'; 
    params.data = JSON.stringify(options.attrs || model.toJSON(options)); 
} 

編輯功能的這一部分:

if (options.data == null && model && (method === 'create' || method === 'update' || method === 'patch')) { 
    params.contentType = 'application/json'; 
    if(options.emulateJSON){ 
    params.data = options.attrs || model.toJSON(options); 
    }else{ 
    params.data = JSON.stringify(options.attrs || model.toJSON(options)); 
    } 
} 

一些其他的線,你會發現主幹增加了一個「模式」鍵,開機自檢的QueryDict。

params.data = params.data ? {model: params.data} : {}; 

編輯這一行:

params.data = params.data ? params.data : {}; 

完蛋了!現在您將數據作爲request.POST QueryDict的一部分。