Pergunta

Eu tenho uma forma de django que estou validando em uma visão normal do Django. Estou tentando descobrir como extrair os erros puros (sem a formatação HTML). Abaixo está o código que estou usando no momento.

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

Com isso, recebo o infame erro de objeto de proxy do Django. Forçar cada erro a Unicode também não fará o truque, porque cada um dos erros ' __unicode__ O método será chamado de maneira efetivamente html.

Alguma ideia?

EDITAR:

Para os interessados, esta é a definição 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')
Foi útil?

Solução 2

Got it after a lot of messing around, testing different things. N.B. I'm not sure whether this works with internationalization as well. This also takes the first validation error for each field, but modifying it to get all of the errors should be rather easy.

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

Outras dicas

This appears to have been improved. The following works in Django 1.3:

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

No need for __unicode__ or lazy translation any more. This also gives a full array of errors for each field.

For Django 1.7+ use Form.errors.as_json() or something like this:

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

The issue here is that error message are lazy translation object. The docs do mention this:

Just make sure you've got ensure_ascii=False and use a LazyEncoder.

We can do this:

import simplejson as json

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

json.dumps can't serialize django's proxy function (like lazy translations).

As documented you should create a new Encoder class:

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)

Use the new Encoder like this:

json.dumps(s, cls=LazyEncoder)

That's all :)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top