2010-04-12 2 views
15

Ich habe mich in Django und jQuery gefunden. Ich habe in Django eine Grundform aufgebaut. Beim Klicken auf "Senden" verwende ich jQuery, um eine AJAX-Anfrage an den Server zu stellen, um meine Daten zu veröffentlichen. Dieses Bit scheint gut zu funktionieren und ich habe es geschafft, die Daten zu speichern. Django gibt einen ValidationError zurück, wenn ein Formular ungültig ist. Könnte mir jemand sagen, wie ich diesen Satz von Fehlermeldungen als Antwort auf meine AJAX-Anfrage zurückgeben kann, damit ich sie leicht mit JS durchgehen und was auch immer tun kann?Rückgabe von Formularfehlern für AJAX-Anfrage in Django

Ich fand this Schnipsel. Betrachtet man das JS-Bit (processJson), sieht man, dass er die Fehlermeldungen zu erhalten scheint, indem er sie aus dem Antwort-HTML extrahiert. Es scheint irgendwie kludgy zu mir. Ist das der beste Weg?

Ich entschuldige mich für jede Vagheit.

Vielen Dank im Voraus.

Antwort

4

Wow, es ist ein Jahr her, seit ich diesen Thread gesehen habe. Nun, mit der Einführung von Django 1.3 und den magischen, undokumentierten klassenbasierten Ansichten ist es einfacher geworden, Djangos sichtbezogene Funktionalität zu erweitern. Mein Projekt, das Djangos Klassen-basierte generische CRUS-Ansichten stark nutzt, benötigt AJAX- und JSON-Funktionalität. Ich habe ein Beispiel hinzugefügt, wie ich Djangos Update-Ansicht geändert habe, um AJAX zu unterstützen und AJAX-Antworten im JSON-Format zurückzugeben. Werfen Sie einen Blick:

def errors_to_json(errors): 
    """ 
    Convert a Form error list to JSON:: 
    """ 
    return dict(
      (k, map(unicode, v)) 
      for (k,v) in errors.iteritems() 
     ) 

class HybridUpdateView(UpdateView): 
    """ 
    Custom update generic view that speaks JSON 
    """ 
    def form_valid(self, form, *args, **kwargs): 
     """ 
     The Form is valid 
     """ 
     form.save() 

     self.message = _("Validation passed. Form Saved.") 
     self.data = None 
     self.success = True 

     payload = {'success': self.success, 'message': self.message, 'data':self.data} 

     if self.request.is_ajax(): 
      return HttpResponse(json.dumps(payload), 
       content_type='application/json', 
      ) 
     else: 
      return super(HybridUpdateView, self).form_valid(
       form, *args, **kwargs 
      ) 

    def form_invalid(self, form, *args, **kwargs): 
     """ 
     The Form is invalid 
     """ 
     #form.save() 

     self.message = _("Validation failed.") 
     self.data = errors_to_json(form.errors) 
     self.success = False 

     payload = {'success': self.success, 'message': self.message, 'data':self.data} 

     if self.request.is_ajax(): 
      return HttpResponse(json.dumps(payload), 
       content_type='application/json', 
      ) 
     else: 
      return super(HybridUpdateView, self).form_invalid(
       form, *args, **kwargs 
      ) 

Die Antwort JSON enthält drei Felder - message (die eine vom Menschen lesbare Nachricht ist), data (die diesen Fall wäre die Liste der Formfehler) und success (die entweder true oder false, ob die Anfrage erfolgreich war oder nicht.). Dies ist in jQuery clientseitig sehr einfach zu handhaben. Eine Probe Antwort wie folgt aussieht:

Content-Type: application/json 

{"message": "Validation failed.", "data": {"host": ["This field is required."]}, "success": false} 

Dies ist nur ein Beispiel dafür, wie ich die Formfehler zu JSON serialisiert und implementiert es in einer klassenbasierten allgemeinen Ansicht kann aber ausgeschlachtet werden, auch mit regelmäßiger Stil Ansichten zu arbeiten.

1

Wenn ich die Front-End-Validierung verwende, enthält die Antwort in der Regel Abschnitte, auf die Sie über die Punktnotation (dataReturned.specificData) zugreifen können.

Basierend auf was und wie Sie Daten zurückgeben, ist der Schlüssel, wie Sie darauf zugreifen. Je modularer Sie mit den zurückgegebenen Daten umgehen, desto leichter ist der Zugriff.

// Start ajax request to server 
$.ajax({ 
    url: '/path_to_service', 
    type: 'POST', 
    data: { key: value }, 

    // Do something with the data 
    success: function(data) { 
     // Data is everything that is returned from the post 
     alert(data); 
     // data.message could be a piece of the entire return 
     alert(data.message); 
    } error: function(data) { // Handle fatal errors } 
}); 
+0

Hallo Calvin, Was ist ein Fehler und was ist ein Erfolg? Gibt es einen Wert, den ich zurückgeben sollte? Wie kann ich auf der Serverseite eine Liste von Validierungsfehlern als JSON zurückgeben, sodass ich sie auf der Clientseite mithilfe der Fehlerfunktion auflisten kann? Das ist das Bit, das mich verwirrt. Danke. –

+0

Erfolg ist, wenn das, was Sie senden, sendet der Service Daten zurück. Bei Erfolg werden Sie die Daten bearbeiten und etwas damit tun (in der Regel ein Feld aktualisieren oder eine Nachricht anzeigen). Fehler ist, wenn der Dienst einen schwerwiegenden Fehler zurückgibt (der Dienst ist defekt oder etwas ist beschädigt). Normalerweise würden Sie false zurückgeben und nichts tun, aber wenn der Dienst für Ihre Sache erforderlich ist, würden Sie dem Benutzer sagen, dass der Dienst ausgefallen ist. Die JSON-Seite der Dinge wird von Ihrem Back-End-Service behandelt. Leider sind meine Back-End-Fähigkeiten nicht ganz da, also kann ich dir nicht sagen, wie man den Service schreibt. – Calvin

0

Sie können meine Adjax-Bibliothek verwenden, um dies für Sie zu behandeln. Installieren Sie die App irgendwo auf dem Weg, verbinden die adjax.js Datei und fügen Sie den folgenden zu Ihrer Ansicht hinzuzufügen:

import adjax 
@adjax.adjax_response 
def my_view(request): 
    # prepare my_form with posted data as normal 
    adjax.form(request, my_form) 

das Formular aktivieren Sie Javascript verwenden nach dem Laden der adjax.js Datei:

$('form').adjaxify(); 

Und genießen: -)

Weitere Funktionen hier: http://adjax.hardysoftware.com.au/how/. Ich werde in der nächsten Woche eine "1.0" Version veröffentlichen, lass mich wissen, wie es läuft. Google Code-Projekt ist hier: http://code.google.com/p/django-adjax/

11

Diese Frage ist alt, aber ich denke, die kürzeste Antwort könnte die Verwendung von json in einer Ansicht wie dieser sein.

from django.utils import simplejson 

def ajax(request): 
    if request.method == 'POST': 
     form = someForm(request.POST) 
     if form.is_valid(): 
      form.save() 
      return HttpResponse(something) 
     else: 
      errors = form.errors 
      return HttpResponse(simplejson.dumps(errors)) 
    else: 
     return HttpResponse(something) 

jetzt können Sie die Daten in Ihrem jquery zugreifen wie Calvin oben beschrieben. JQuery macht es einfach, die Daten zu verarbeiten, Sie so etwas tun könnte:

var errors = jQuery.parseJSON(data) 
    alert(errors.username) 
+0

Das funktioniert. Danke erschrocken. Ich hatte den Eindruck, dass du einen JSON-Dump von "form.errors.as_ul()" oder einem Äquivalent machen musst ... aber das funktioniert besser. Prost. – bento

+0

Ich habe Syntaxfehler in Zeile 1, Spalte t in Daten, wenn 'jQuery.parseJSON (Daten)'. Meine Daten beginnen mit 'Object {readyState: 4, getResponseHeader: .aj ...' –

0

Ich weiß, das ist ein alter und beantwortete Frage! Möchte noch dazu beitragen. Die Lösung, die ich am meisten mag, ist die Verwendung eines Dekorators für Methoden, die JSON Fehler enthalten sollten.

import traceback,sys,simplejson 

def unhandled(e): 
    """ 
    Helper function to format an exception and it's stack 
    """ 
    exc_type, exc_value, exc_traceback = sys.exc_info() 
    lines = traceback.format_exception(exc_type, exc_value, exc_traceback) 
    stack = ''.join(line for line in lines) 
    return HttpResponse(simplejson.dumps({"error":-1, "response": e.message ,"stack":stack}), content_type='application/json') 


def use_json_except(f): 
    def new_f(*args): 
    try: 
     return f(*args) 
    except Exception as e: 
     return unhandled(e) 
    return new_f 

Dann definieren Sie Ihre Django-Methode:

@use_json_except 
def add_annotation(request): 
    .... 

Der Dekorateur wird alle nicht abgefangenen Ausnahmen und geben ein Json mit dem Fehler Info und den Stapel fangen.

Ich persönlich finde dies eine sehr gute Lösung für einen Django-Server, der HTML- und JSON-Antworten mischt.