2012-08-30 62 views
5

Soy nuevo en Backbone.js y estoy tratando de guardar una instancia de modelo. Estoy usando django como mi servidor. Código ladoGuardando los datos del modelo Backbone.js. Datos no enviados correctamente

Cliente:

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

}); 

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

csrfmiddlewaretoken está configurado correctamente antes de enviar los datos.

Pasé por la función jQuery $ .ajax llamada internamente por Backbone.sync y encontré que el objeto modelo contiene los datos correctos.

Sin embargo, el request.POST recibido por el servidor es

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

en lugar de los datos reales. ¿Alguna idea de dónde me estoy equivocando?

Actualización: Hice una solución rápida al establecer Backbone.emulateJSON en verdadero. Pero de acuerdo con los comentarios en el código Backbone (0.9.2) está destinado a servidores heredados. Estoy usando Django 1.4.1. ¿Significa que django 1.4.1 es incompatible?

Actualización 2: Cuando fijo Backbone.emulateJSON-false, me sale el siguiente error en Firefox pero fracasa en silencio en cromo.

"[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]" 

estoy usando jQuery para el Ajax como el preferido por la espina dorsal y parece que el error puede estar en jQuery.

Actualización 3: Lo resolvé anulando el $ .ajax utilizado por Backbone.sync con el mío. Todavía es una solución rápida.

Backbone.js Verson: 0.9.2

jQuery versión: 1.8.0. También intenté con 1.7.2. Mismo resultado.

+0

Puede ver su panel de red y ver los datos que se publican en su servidor. No estoy familiarizado con Django, pero su problema definitivamente parece un problema del lado del servidor y no es un problema con Backbone. – TYRONEMICHAEL

+0

@TyroneMichael Gracias por la sugerencia. El panel de red en cromo muestra que el modelo se envía como un objeto simple en Carga de solicitud. Pero en Firefox obtuve el error escrito en la Actualización 2. – Pramod

+0

No creo que los datos se envíen como una cadena (Eche un vistazo [aquí] (http://communities.rightnow.com/posts/9580c78607)). ¿Obtiene este error cuando Emulate JSON es falso? ¿Qué sucede en FF cuando comenta Emulate JSON = false? – TYRONEMICHAEL

Respuesta

9

Estaba teniendo un problema similar y gracias a un trabajo de detective/suerte lo descubrí. El problema es que, de manera predeterminada, Backbone envía los datos POST como una cadena codificada JSON en el cuerpo de la solicitud, no como parte del request.POST QueryDict. Entonces, para obtener los datos en este caso, deberá usar la biblioteca python json y llamar al json.loads(request.body) en la vista de Django para leer los datos correctamente.

Como un aparte, la razón por la que Backbone.emulateJSON = true; funciona es porque el Backbone envía el JSON a Django a través del mecanismo "heredado" que lo hace aparecer en el request.POST QueryDict.

+0

... o 'json.loads (request.raw_post_data)' para versiones anteriores de django –

1

Si desea que los datos estén disponibles en QueryDict request.POST, tendrá que anular el método Backbone.sync.

Antes que nada, tendrá que establecer Backbone.emulateJSON en verdadero.

Puede echar un vistazo al método Backbone.sync sobre here. Notará que los atributos del modelo están codificados.

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

Editar esta parte de la función de:

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

En alguna otra línea se dará cuenta de que Backbone agrega una clave de 'modelo' a la QueryDict POST.

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

Editar esta línea a:

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

Eso es todo! Ahora tendrá los datos como parte de request.POST QueryDict.

Cuestiones relacionadas