如何保持排序字典的顺序传递给jsonify()函数?

时间:2019-01-30 17:18:35

标签: python flask

我试图将排序的字典传递给jsonify()函数,然后从JS代码中使用它来取出值。我看到的是,即使我传递正确的值,由于某种原因,它们也会由jsonify重新排序。


json_data = {
    "11": {
        "j_id": "out",
    },
    "aa": {
        "j_id": "in",
    },
    "bb": {
        "j_id": "out",
    },
}

jkeys=json_data.keys()
sorted_json = sorted(jkeys, key=lambda x: json_data[x]['j_id'], reverse=False)

new_sorted=OrderedDict()
for rec in sorted_json:
    new_sorted[rec]=json_data[rec]

print('sort dict: {}'.format(new_sorted))

输出正确,我可以看到适当的值,在我的情况下应该是:aa,11,bb

>>> from collections import OrderedDict
>>>
>>> json_data = {
...     "11": {
...         "j_id": "out",
...     },
...     "aa": {
...         "j_id": "in",
...     },
...     "bb": {
...         "j_id": "out",
...     },
... }
>>>
>>> jkeys=json_data.keys()
>>> sorted_json = sorted(jkeys, key=lambda x: json_data[x]['j_id'], reverse=False)
>>>
>>> new_sorted=OrderedDict()
>>> for rec in sorted_json:
...     new_sorted[rec]=json_data[rec]
...
>>> print('sort dict: {}'.format(new_sorted))
sort dict: OrderedDict([('aa', {'j_id': 'in'}), ('11', {'j_id': 'out'}), ('bb', {'j_id': 'out'})])

不幸的是,当我将其传递给jsonify()函数,然后输出flask数据的console.log()输出时,顺序变为:11,aa,bb。除此之外,我进行了一些研究,找到了this的堆栈溢出答案,并得出了一些good documentation notes,其中明确指出将 JSON_SORT_KEYS 设置为 False 不推荐的方式。然后我检查了this github issue,看来烧瓶中的问题没有完全解决。

以我的情况解决此问题的最佳方法是什么?

2 个答案:

答案 0 :(得分:20)

在应用定义后,将此配置行添加到您的代码中:

app = Flask(__name__)
app.config['JSON_SORT_KEYS'] = False

答案 1 :(得分:1)

JSON对象是无序结构,您的浏览器很容易最终再次放弃JSON密钥的顺序。

来自JSON standard

  

对象是一组无序的名称/值对。

我强调大胆。为了保持符合标准,请使用 list (JSON数组)来捕获特定的订单。

也就是说,可以使用Flask来保留您用OrderedDict设置的顺序。

  • 使用JSON_SORT_KEYS = False禁用应用程序范围内的排序。

    使用默认设置True时,jsonify()对键进行排序,以提供可缓存的稳定HTTP响应。文档警告不要禁用此功能,只是要使您意识到将其设置为False的弊端。

    但是,如果您使用的是Python 3.6或更高版本,则实际上并不会产生这种担忧,因为从该版本开始,内置的dict类型也为preserves insertion order,因此,顺序从一个Python运行更改为另一个。

  • 而不是使用jsonify(),而是直接使用flask.json.dumps(),并创建自己的Response对象。传递sort_keys=False

    from flask import json
    
    response = current_app.response_class(
        json.dumps(new_sorted, sort_keys=False),
        mimetype=current_app.config['JSONIFY_MIMETYPE'])