2009-06-12 3 views
35

У меня есть форма Django, которую я проверяю в обычном представлении Django. Я пытаюсь выяснить, как извлечь чистые ошибки (без форматирования HTML). Ниже приведен код, который я использую в данный момент.Возвращение ошибок формы Django в JSON

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

С этим я получаю позорную ошибку прокси-объекта из Django. Принуждение каждой ошибки в Юникод также не приведет к трюку, потому что тогда каждый из методов ошибки __unicode__ будет называться эффективно HTML-izing.

Любые идеи?

EDIT:

Для тех, кто заинтересован, это определение 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

Принятый ответ устарел. См. Https://stackoverflow.com/a/28256365/604511 – aitchnyu

ответ

24

Понял после много возиться, испытывая разные вещи. Нотабене Я не уверен, работает ли это с интернационализацией. Это также принимает первую ошибку проверки для каждого поля, но ее изменение для получения всех ошибок должно быть довольно простым.

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

, вы также можете попробовать: 'form.error_class.as_text (v)' on 'v' (который является списком ошибок) вместо вызова' __unicode __() 'on каждый элемент 'v' – tehfink

+3

errors = dict ([(k, form.error_class.as_text (v)) для k, v в form.errors.items()]) return json_response ({" errors ": errors}) – digitalPBK

+2

Я нашел следующее, чтобы обеспечить лучшую структуру, а также обслуживать элементы с более чем 1 ошибкой: '{k: v для k, v в контексте ['signup_form']. Errors.items()}' – DanH

4

Проблема заключается в том, что сообщение об ошибке является ленивым объектом перевода. docs Обязательно укажите это:

Просто убедитесь, что у вас есть secure_ascii = False и используйте LazyEncoder.

+0

Это путь. Я добавил ответ, который дает некоторые детали этого подхода. – bjunix

30

Это, кажется, было улучшено. Следующие работы в Django 1.3:

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

Нет необходимости __unicode__ или ленивым перевод больше. Это также дает полный массив ошибок для каждого поля.

+0

Это не работает – digitalPBK

+0

@digitalPBK заботиться о разработке? – SystemParadox

+1

Я получил ту же ошибку, что и при использовании объекта form.errors (некий класс Lazy) не может быть сериализован. – digitalPBK

1

Мы можем сделать это:

import simplejson as json 

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

json.dumps не может сериализовать функции прокси Джанго (как ленивые переводы).

Как documented вы должны создать новый класс кодировщик:

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) 

Используйте новый кодировщик, как это:

json.dumps(s, cls=LazyEncoder) 

Это все :)

19

Для Джанго 1.7+ использовать Form.errors.as_json() или что-то вроде этого:

errors = {f: e.get_json_data() for f, e in form.errors.items()} 
return json_response(success=False, data=errors) 
Смежные вопросы