Devolver errores puros de Django en JSON
unicode django-forms (6)
Tengo un formulario de Django que estoy validando en una vista normal de Django. Estoy intentando descubrir cómo extraer los errores puros (sin el formato HTML). A continuación está el código que estoy usando en este momento.
return json_response({ ''success'' : False,
''errors'' : form.errors })
Con esto, obtengo el infame error de objeto proxy de Django. Forzar cada error en Unicode tampoco hará el truco, porque entonces cada uno de los errores del __unicode__
''se llamará HTML-izing efectivamente.
¿Algunas ideas?
EDITAR:
Para aquellos interesados, esta es la definición 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'')
El problema aquí es que el mensaje de error es un objeto de traducción lento. Los docs sí lo mencionan:
Solo asegúrate de que tienes ensure_ascii = False y usa un LazyEncoder.
Esto parece haber sido mejorado. Los siguientes trabajos en Django 1.3:
return json_response({
''success'': False,
''errors'': dict(form.errors.items()),
})
Ya no es necesario __unicode__
o una traducción perezosa. Esto también proporciona una gama completa de errores para cada campo.
Lo tengo después de mucho perder el tiempo, probando diferentes cosas. NB No estoy seguro de si esto también funciona con la internacionalización. Esto también toma el primer error de validación para cada campo, pero modificarlo para obtener todos los errores debería ser bastante fácil.
return json_response({ ''success'' : False,
''errors'' : [(k, v[0].__unicode__()) for k, v in form.errors.items()] })
Para Django 1.7+ use Form.errors.as_json() o algo como esto:
errors = {f: e.get_json_data() for f, e in form.errors.items()}
return json_response(success=False, data=errors)
Podemos hacer esto:
import simplejson as json
errors = json.dumps(form.errors)
return HttpResponse(errors, mimetype=''application/json'')
json.dumps
no puede serializar la función proxy de django (como las traducciones flojas).
Según lo documented , debes crear una nueva clase de codificador:
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)
Usa el nuevo codificador así:
json.dumps(s, cls=LazyEncoder)
Eso es todo :)