Returning pure Django form errors in JSON

前端 未结 6 2005
青春惊慌失措
青春惊慌失措 2020-12-12 16:50

I have a Django form which I\'m validating in a normal Django view. I\'m trying to figure out how to extract the pure errors (without the HTML formatting). Below is the code

相关标签:
6条回答
  • 2020-12-12 17:24

    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.

    0 讨论(0)
  • 2020-12-12 17:35

    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 :)

    0 讨论(0)
  • 2020-12-12 17:37

    We can do this:

    import simplejson as json
    
    errors = json.dumps(form.errors)
    return HttpResponse(errors, mimetype='application/json')
    
    0 讨论(0)
  • 2020-12-12 17:47

    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.

    0 讨论(0)
  • 2020-12-12 17:49

    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()] })
    
    0 讨论(0)
  • 2020-12-12 17:50

    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)
    
    0 讨论(0)
提交回复
热议问题