I'm trying to pass sorted dictionary to jsonify() function and then use it from within JS code to take out values. What I see there is that even though I pass correct values, they are reordered by jsonify for some reason.
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))
The output is correct and I can see proper values which in my case should be: 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'})])
Unfortunately, when I pass this to jsonify() function and then for example console.log() output of flask data, the orderd becomes like that: 11, aa, bb. Additionally to that, I've done some research and found this stackoverflow answer, leading to some good documentation notes which clearly states that setting JSON_SORT_KEYS to False is not recommended way. Then I checked this github issue and it seems that problem is not fully resolved in flask.
What would be the best way to fix it in my case?
No, returning a dict in Flask will not apply jsonify automatically. In fact, Flask route cannot return dictionary.
Flask jsonify is defined as a functionality within Python's capability to convert a json (JavaScript Object Notation) output into a response object with application/json mimetype by wrapping up a dumps( ) function for adding the enhancements.
Add this config line to your code after the app definition:
app = Flask(__name__) app.config['JSON_SORT_KEYS'] = False
JSON objects are unordered structures, and your browser could easily end up discarding the order of your JSON keys again.
From the JSON standard:
An object is an unordered set of name/value pairs.
Bold emphasis mine. To remain standards compliant, use a list (JSON array) to capture a specific order.
That said, Flask can be made to preserve the order you set with OrderedDict
.
Disable sorting app-wide, with JSON_SORT_KEYS = False
.
With this setting at the default True
, jsonify()
sorts keys to provide stable HTTP responses that are cacheable. The documentation warns against disabling this only to make you aware of the downside of setting this to False
.
However, if you are using Python 3.6 or newer this concern doesn't actually play because as of that version the built-in dict
type also preserves insertion order, and so there is no problem with the order changing from one Python run to the next.
Instead of using jsonify()
, use flask.json.dumps()
directly, and create your own Response
object. Pass in 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'])
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With