2012-08-30 6 views
5

Ich bin neu in Backbone.js und versuche eine Modellinstanz zu speichern. Ich benutze Django als meinen Server.Speichern von Backbone.js Modelldaten. Daten wurden nicht korrekt gesendet

Client-Seite Code:

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

}); 

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

csrfmiddlewaretoken richtig eingestellt ist, bevor die Daten gesendet werden.

Ich trat durch die jQuery $ .ajax Funktion, die intern von Backbone.sync aufgerufen wird und festgestellt, dass das Modellobjekt die richtigen Daten enthält.

jedoch die request.POST vom Server empfangen wird

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

anstelle der tatsächlichen Daten. Irgendeine Idee, wo ich falsch liege?

Update: Ich habe eine schnelle Lösung durch die Einstellung Backbone.emulateJSON auf True. Aber laut den Kommentaren im Backbone (0.9.2) -Code ist es für ältere Server gedacht. Ich benutze Django 1.4.1. Bedeutet es, dass Django 1.4.1 nicht kompatibel ist?

Update 2: Wenn ich Backbone.emulateJSON-false gesetzt, ich die folgenden Fehler in Firefox erhalten, aber es scheitert stumm in Chrom.

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

Ich bin mit jQuery für AJAX wie Backbone bevorzugt, und es scheint der Fehler in jQuery sein könnte.

Update 3: Ich löste es durch Überschreiben der $ .ajax von Backbone.sync mit meinem eigenen verwendet. Es ist immer noch eine schnelle Lösung.

Backbone.js verson: 0.9.2

jQuery-Version: 1.8.0. Auch mit 1.7.2 versucht. Gleiches Ergebnis.

+0

Sie können sich Ihren Netzwerkbereich ansehen und die Daten sehen, die auf Ihrem Server veröffentlicht werden. Ich bin mit Django nicht vertraut, aber Ihr Problem scheint definitiv ein serverseitiges Problem zu sein und kein Problem mit Backbone. – TYRONEMICHAEL

+0

@TyroneMichael Danke für den Vorschlag. Das Netzwerkfenster in Chrom zeigt, dass das Modell als einfaches Objekt in Request Payload gesendet wird. Aber in Firefox habe ich den Fehler in Update 2 geschrieben. – Pramod

+0

Ich glaube nicht, dass die Daten als String gesendet werden (schauen Sie [hier] (http://communities.rightnow.com/posts/9580c78607)). Erhalten Sie diesen Fehler, wenn JSON-Emulation falsch ist? Was passiert in FF, wenn Sie auskommentieren Emulate JSON = false? – TYRONEMICHAEL

Antwort

9

Ich hatte ein ähnliches Problem und durch einige Detektivarbeit/Glück habe ich es herausgefunden. Das Problem ist, dass Backbone standardmäßig die POST-Daten als JSON-codierte Zeichenfolge im Hauptteil der Anfrage nicht als Teil des QueryDict request.POST sendet. Um die Daten in diesem Fall zu erhalten, müssten Sie die python json-Bibliothek verwenden und json.loads(request.body) in der Django-Ansicht aufrufen, um die Daten richtig zu lesen.

Der Grund, warum die Einstellung Backbone.emulateJSON = true; funktioniert, ist, weil dann Backbone sendet die JSON nach Django durch die "Legacy" -Mechanismus, der es im request.POST QueryDict erscheint.

+0

... oder 'json.loads (request.raw_post_data)' für ältere Versionen von django –

1

Wenn die Daten in der QueryDict request.POST verfügbar sein sollen, müssen Sie die Methode Backbone.sync überschreiben.

Zuerst müssen Sie Backbone.emulateJSON auf True setzen.

Sie können sich die Backbone.sync-Methode über here ansehen. Sie werden feststellen, dass die Modellattribute stringifiziert sind.

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

bearbeiten Teil der Funktion zu:

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

Auf einer anderen Zeile zeigt, dass Backbone bemerken fügt ein ‚Modell‘ Schlüssel für die POST QueryDict.

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

Bearbeiten Sie diese Zeile an:

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

Das ist es! Jetzt haben Sie die Daten als Teil von request.POST QueryDict.

Verwandte Themen