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

zer*_*ool 21 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))
Run Code Online (Sandbox Code Playgroud)

输出是正确的,我可以看到正确的值,在我的情况下应该是: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'})])
Run Code Online (Sandbox Code Playgroud)

不幸的是,当我将它传递给 jsonify() 函数,然后将它传递给烧瓶数据的例如 console.log() 输出时,顺序变成了这样:11,aa,bb。除此之外,我做了一些研究并找到了这个stackoverflow 答案,导致了一些很好的文档说明,其中明确指出不推荐将JSON_SORT_KEYS设置为False 的方法。然后我检查了this github issue,似乎问题在flask中没有完全解决。

在我的情况下,修复它的最佳方法是什么?

Sae*_* Ir 43

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

app = Flask(__name__)
app.config['JSON_SORT_KEYS'] = False
Run Code Online (Sandbox Code Playgroud)

  • 谢谢,这绝对是疯狂的, false 不是默认值 (5认同)
  • 摘要:对于 Flask 2.3 之前的版本,请使用 `app.config['JSON_SORT_KEYS'] = False`。对于 Flask 2.3 及更高版本,请使用 `app.json.sort_keys = False`。 (2认同)

Seb*_*Seb 15

set 的解决方案在最新版本的Flask (2.3)app.config['JSON_SORT_KEYS'] = False中不再起作用,在 Flask 的基于 asyncio 的同级Quart中也不起作用。

关闭排序的新方法是更新sort_keys应用程序JSONProvider实例上的属性:

from flask import Flask  # or from quart import Quart, etc.

app = Flask(__name__)
app.json.sort_keys = False
Run Code Online (Sandbox Code Playgroud)

或者如果您已经在使用自定义JSONProvider子类:

from flask import Flask
from flask.json.provider import DefaultJSONProvider

class CustomJSONProvider(DefaultJSONProvider):
    sort_keys = False

app = Flask(__name__)
app.json = CustomJSONProvider(app)
Run Code Online (Sandbox Code Playgroud)


Mar*_*ers 12

JSON 对象是无序结构,您的浏览器很容易再次丢弃 JSON 键的顺序。

JSON 标准

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

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

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

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

    随着在默认此设置Truejsonify()各种按键提供了可缓存稳定的HTTP响应。文档警告不要禁用它只是为了让您意识到将其设置为False.

    但是,如果您使用的是 Python 3.6 或更高版本,则实际上不会出现这种问题,因为从该版本开始,内置dict类型也保留了插入顺序,因此从一个 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'])
    
    Run Code Online (Sandbox Code Playgroud)