在 JSON 中返回纯 Django 表单错误

Posted

技术标签:

【中文标题】在 JSON 中返回纯 Django 表单错误【英文标题】:Returning pure Django form errors in JSON 【发布时间】: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')

【问题讨论】:

接受的答案已过时。见***.com/a/28256365/604511 【参考方案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)

【讨论】:

以上是关于在 JSON 中返回纯 Django 表单错误的主要内容,如果未能解决你的问题,请参考以下文章

ffprobe 或 avprobe 在 JSON 输出中返回纯文本错误

使用ajax将它们作为json后如何循环遍历django表单错误

在 Django 中,如何通过错误返回 File 输入的值?

在 Django 中发生错误时呈现管理表单

如何让 Django 视图返回表单错误

Rails:如果表单返回验证错误,则保持 JSON 表单字段填充