web-dev-qa-db-ja.com

JSONで純粋なDjangoフォームエラーを返す

通常の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')
39
Deniz Dogan

lotいじり回して、さまざまなことをテストした後、手に入れました。 N.B.これが国際化でも機能するかどうかはわかりません。これも各フィールドの最初の検証エラーを取りますが、すべてのエラーを取得するように変更するのはかなり簡単です。

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

これは改善されたようです。以下はDjango 1.3で動作します:

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

__unicode__や怠惰な翻訳はもう必要ありません。これにより、各フィールドのエラーの完全な配列も得られます。

33
SystemParadox

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)
27
lampslave

ここでの問題は、エラーメッセージが怠惰な翻訳オブジェクトであるということです。 docs これについて言及してください:

Sure_ascii = Falseがあることを確認し、LazyEncoderを使用してください。

4
Arthur Debert

できるよ:

import simplejson as json

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

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)

それで全部です :)

1
bjunix