【问题标题】:Returning pure Django form errors in JSON在 JSON 中返回纯 Django 表单错误
【发布时间】:2010-11-02 10:51:18
【问题描述】:

我有一个 Django 表单,我正在一个普通的 Django 视图中验证它。我试图弄清楚如何提取纯错误(没有 HTML 格式)。以下是我目前正在使用的代码。

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

有了这个,我从 Django 中得到了臭名昭著的代理对象错误。将每个错误强制转换为 Unicode 也无济于事,因为这样每个错误的 __unicode__ 方法将被有效地调用 HTML 化。

有什么想法吗?

编辑:

对于那些感兴趣的人,这是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')

【问题讨论】:

标签: django json unicode django-forms lazy-evaluation


【解决方案1】:

经过 很多 的折腾,测试不同的东西后得到它。注:我不确定这是否也适用于国际化。这也需要每个字段的第一个验证错误,但修改它以获取所有错误应该相当容易。

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

【讨论】:

  • 你也可以尝试:form.error_class.as_text(v) on v(这是一个ErrorList),而不是在v的每个项目上调用__unicode__()
  • errors = dict([(k, form.error_class.as_text(v)) for k, v in form.errors.items()]) return json_response({"errors":errors})
  • 我发现以下内容可以提供更好的结构,也可以满足超过 1 个错误的项目:{k: v for k, v in context['signup_form'].errors.items()}
【解决方案2】:

这里的问题是错误消息是惰性翻译对象。 docs 确实提到了这一点:

只要确保你有 ensure_ascii=False 并使用 LazyEncoder。

【讨论】:

  • 这就是要走的路。我添加了一个答案,为这种方法提供了一些细节。
【解决方案3】:

这似乎已得到改进。以下适用于 Django 1.3:

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

不再需要__unicode__ 或懒惰翻译。这也为每个字段提供了完整的错误数组。

【讨论】:

  • @digitalPBK 需要详细说明吗?
  • 我得到了和使用form.errors时一样的错误,(一些懒惰的类)对象不能被序列化。
  • 对我也不起作用(django 1.4)...为什么投票率如此之高?
  • 在 Django 开发中工作。我猜它适用于 1.5 及更高版本。
【解决方案4】:

我们可以这样做:

import simplejson as json

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

【讨论】:

    【解决方案5】:

    json.dumps 无法序列化 django 的代理功能(如惰性翻译)。

    作为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)
    

    就是这样:)

    【讨论】:

      【解决方案6】:

      对于 Django 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)
      

      【讨论】:

        猜你喜欢
        • 2013-04-20
        • 1970-01-01
        • 2011-02-07
        • 2013-04-01
        • 1970-01-01
        • 2016-10-26
        • 1970-01-01
        • 2014-02-03
        • 2010-12-26
        相关资源
        最近更新 更多