保存Backbone.js模型数据。数据未正确发送

时间:2012-08-30 19:23:51

标签: jquery ajax django backbone.js

我是Backbone.js的新手,我正在尝试保存模型实例。 我正在使用django作为我的服务器。

客户端代码:

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

});

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

csrfmiddlewaretoken在发送数据之前设置正确。

我逐步完成了内部调用的jQuery $ .ajax函数 Backbone.sync并发现模型对象包含正确的数据。

但是,服务器收到的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.emulateJSON设置为false时,我在Firefox中遇到以下错误,但它在Chrome中无声地失败。

   "[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作为Backbone首选的ajax,似乎错误可能在jQuery中。

更新3 :我通过覆盖Backbone.sync使用的$ .ajax解决了这个问题。它仍然是一个快速修复。

Backbone.js verson:0.9.2

jQuery版本:1.8.0。也试过1.7.2。结果相同。

2 个答案:

答案 0 :(得分:9)

我有一个类似的问题,并通过一些侦探工作/运气我想出来了。问题是默认情况下,Backbone将POST数据作为JSON编码的字符串发送到请求正文中,而不是request.POST QueryDict的一部分。因此,要获得这种情况下的数据,您必须使用python json库并在Django视图中调用json.loads(request.body)来正确读取数据。

顺便说一句,设置Backbone.emulateJSON = true;的原因是因为Backbone通过“遗留”机制将JSON发送到Django,这使得它出现在request.POST QueryDict中。

答案 1 :(得分: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));
  }
}

在其他一些行上,您会注意到Backbone在POST QueryDict中添加了“模型”键。

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

将此行编辑为:

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

多数民众赞成!现在,您将把数据作为request.POST QueryDict。

的一部分