2009-06-12 14 views
35

Mam formularz Django, który sprawdzam w normalnym widoku Django. Próbuję dowiedzieć się, jak wyodrębnić czyste błędy (bez formatowania HTML). Poniżej znajduje się kod, którego używam w tej chwili.Zwracanie czystych błędów formularza Django w JSON

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

Dzięki temu otrzymuję niesławny błąd obiektu proxy od Django. Wymuszenie każdego błędu w Unicode też nie wystarczy, ponieważ wtedy każda z metod "błędu" zostanie nazwana efektywnie HTML-izingiem.

Wszelkie pomysły?

EDIT:

Dla zainteresowanych, jest to definicja 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

Przyjęta odpowiedź jest nieaktualna. Zobacz https://stackoverflow.com/a/28256365/604511 – aitchnyu

Odpowiedz

24

Got to po partii o aprowizacji, testując różne rzeczy. N.B. Nie jestem pewien, czy to też działa z umiędzynarodowieniem. To również powoduje pierwszy błąd sprawdzania poprawności dla każdego pola, ale modyfikowanie go w celu uzyskania wszystkich błędów powinno być raczej łatwe.

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

możesz również spróbować: 'form.error_class.as_text (v)' na 'v' (który jest listą błędów), zamiast wywoływania' __unicode __() 'na każdy element 'v' – tehfink

+3

errors = dict ([(k, form.error_class.as_text (v)) dla k, v w form.errors.items()]) return json_response ({" errors ": errors}) – digitalPBK

+2

Znalazłem następujące elementy, aby zapewnić lepszą strukturę, a także uwzględnić elementy z więcej niż 1 błędem: '{k: v dla k, v w kontekście ['signup_form']. Errors.items()}' – DanH

4

Problem polega na tym, że komunikat o błędzie jest leniwym obiektem do tłumaczenia. The docs wspomnieć:

Upewnij się, że masz sure_ascii = False i użyj LazyEncoder.

+0

To jest droga. Dodałem odpowiedź, która podaje pewne szczegóły tego podejścia. – bjunix

30

Wygląda na to, że został poprawiony. Następujące prace w Django 1.3:

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

Nie potrzeba __unicode__ lub tłumaczenia leniwe więcej. Daje to również pełną listę błędów dla każdego pola.

+0

To nie wydaje się działać – digitalPBK

+0

@ digitalPBK opieki do opracowania? – SystemParadox

+1

Wystąpił ten sam błąd, co przy korzystaniu z form.errors, obiektu (niektóre klasy Lazy) nie można serializować. – digitalPBK

1

Możemy to zrobić:

import simplejson as json 

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

json.dumps funkcję proxy Django nie może szeregować (jak leniwe tłumaczeń).

Jak documented należy utworzyć nową klasę Encoder:

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) 

użyć nowego nadajnika tak:

json.dumps(s, cls=LazyEncoder) 

To wszystko :)

19

Dla Django 1.7+ lub użyć Form.errors.as_json() coś takiego:

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