2009-06-12 5 views
35

J'ai un formulaire Django que je valide dans une vue Django normale. J'essaie de comprendre comment extraire les erreurs pures (sans le formatage HTML). Voici le code que j'utilise en ce moment.Retour des erreurs de forme de Django pur dans JSON

return json_response({ 'success' : False, 
         'errors' : form.errors }) 

Avec ceci, j'obtiens l'erreur infâme d'objet proxy de Django. Forcer chaque erreur en Unicode ne fera pas l'affaire non plus, car alors chacune des méthodes __unicode__ des erreurs sera appelée HTML-izing efficacement.

Des idées?

EDIT:

Pour les intéressés, voici la définition de json_response:

def json_response(x): 
    import json 
    return HttpResponse(json.dumps(x, sort_keys=True, indent=2), 
         content_type='application/json; charset=UTF-8') 
+0

La réponse acceptée est obsolète. Voir https://stackoverflow.com/a/28256365/604511 – aitchnyu

Répondre

24

Got après beaucoup de déconner, de tester des choses différentes. N.B. Je ne suis pas sûr que cela fonctionne aussi avec l'internationalisation. Cela prend également la première erreur de validation pour chaque champ, mais le modifier pour obtenir toutes les erreurs devrait être plutôt facile.

return json_response({ 'success' : False, 
         'errors' : [(k, v[0].__unicode__()) for k, v in form.errors.items()] }) 
+5

vous pouvez aussi essayer: 'form.error_class.as_text (v)' on 'v' (qui est une ErrorList), au lieu d'appeler' __unicode __() ' chaque élément de 'V' – tehfink

+3

erreurs = dict ([(k, form.error_class.as_text (v)) pour k, v dans form.errors.items()]) json_response de retour ({ "erreurs": erreurs}) – digitalPBK

+2

J'ai trouvé ce qui suit pour fournir une meilleure structure, et vous trouverez aussi des articles avec plus de 1 erreur: '{k: v. pour k, v dans le contexte [ « de signup_form »] errors.items()}' – DanH

4

Le problème ici est que le message d'erreur est un objet de traduction paresseux. Le docs mentionne ceci:

Assurez-vous juste que vous avez assuré_ascii = Faux et utilisez un LazyEncoder.

+0

C'est le chemin à parcourir. J'ai ajouté une réponse qui donne quelques détails à cette approche. – bjunix

30

Cela semble avoir été amélioré. Les travaux suivants dans Django 1.3:

return json_response({ 
    'success': False, 
    'errors': dict(form.errors.items()), 
}) 

Pas besoin de traduction __unicode__ ou plus paresseux. Cela donne également un tableau complet des erreurs pour chaque champ.

+0

Cela ne semble pas fonctionner – digitalPBK

+0

@digitalPBK soin d'élaborer? – SystemParadox

+1

J'ai eu la même erreur que lors de l'utilisation de form.errors, l'objet (Some Lazy class) ne peut pas être sérialisé. – digitalPBK

1

Nous pouvons le faire:

import simplejson as json 

errors = json.dumps(form.errors) 
return HttpResponse(errors, mimetype='application/json') 
0

json.dumps ne peut pas sérialiser la fonction proxy de django (comme traductions paresseux).

Comme documented vous devez créer une nouvelle classe de codeur:

import json 
from django.utils.functional import Promise 
from django.utils.encoding import force_text 
from django.core.serializers.json import DjangoJSONEncoder 

class LazyEncoder(DjangoJSONEncoder): 
    def default(self, obj): 
     if isinstance(obj, Promise): 
      return force_text(obj) 
     return super(LazyEncoder, self).default(obj) 

Utilisez le nouveau codeur comme ceci:

json.dumps(s, cls=LazyEncoder) 

C'est tout :)

19

Pour Django 1.7+ utiliser Form.errors.as_json() ou quelque chose comme ceci:

errors = {f: e.get_json_data() for f, e in form.errors.items()} 
return json_response(success=False, data=errors) 
Questions connexes