New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

jsonify() ignores the sort order of an OrderedDict #974

Closed
wmax opened this Issue Feb 6, 2014 · 8 comments

Comments

Projects
None yet
6 participants
@wmax
Copy link

wmax commented Feb 6, 2014

Hi, I would like to know whether this is a bug or a feature.

Example:

from flask import Flask, jsonify
from collections import OrderedDict
app = Flask('__name__')

@app.route('/')
def jsonify_test():
    unsorted_dict = {'foo': 1, 'bar': 4, 'baz': 0}
    sorted_dict = OrderedDict(sorted(unsorted_dict.items(), key=lambda x: x[1]))
    return jsonify(sorted_dict)

if __name__ == '__main__':
    app.run(debug = True)

Result:

{
    "bar": 4, 
    "baz": 0, 
    "foo": 1
}
@ThiefMaster

This comment has been minimized.

Copy link
Member

ThiefMaster commented Feb 6, 2014

JavaScript objects are not ordered. So it's pointless to take the order of an OrderedDict into account when converting it to JSON. If you need the order, jsonify its .items() (which will give you an array of arrays in JS).

@wmax

This comment has been minimized.

Copy link

wmax commented Feb 6, 2014

Agreed(on the "makes no sense in JS" part).
I've worked around by using a prettified json.dumps() output directly, because I didn't like the sparse rep. of the nested list produced by jsonify().

However I've just noticed that the dict seems to be sorted by "key" after jsonifying, I've tried it with a pretty long list(more then 50 keys) so it doesn't looks like a coincidence.

@iiSeymour

This comment has been minimized.

Copy link

iiSeymour commented Feb 7, 2014

This is a feature.

By default Flask will serialize JSON objects in a way that the keys are ordered. This is done in order to ensure that independent of the hash seed of the dictionary the return value will be consistent to not trash external HTTP caches. You can override the default behaviour by setting app.config["JSON_SORT_KEYS"] = False.

@mitsuhiko mitsuhiko closed this Feb 8, 2014

@obskyr

This comment has been minimized.

Copy link

obskyr commented Jan 12, 2016

Actually, it seems there is a problem with JSON_SORT_KEYS = False too. Even then, it doesn't respect the order of an OrderedDict, and provides the properties in arbitrary order. Surely that isn't intentional?

@ThiefMaster

This comment has been minimized.

Copy link
Member

ThiefMaster commented Jan 12, 2016

This cannot be avoided. Object keys in JS have no order - just like python dict keys. If you need to keep the order you usually need to pass a list of [key, value] lists (e.g. the .items() of the OrderedDict) and then (if needed) build a lookup dict in JS.

AFAIK some engines keep the order for object literals, others don't - AFAIK the standard does not require any specific behavior related to the key order.

@obskyr

This comment has been minimized.

Copy link

obskyr commented Jan 12, 2016

No, I'm talking about the actual literal order in the JSON provided - nothing related to JS. That being arbitrary can definitely be avoided.

@ThiefMaster

This comment has been minimized.

Copy link
Member

ThiefMaster commented Jan 12, 2016

ah.. I guess that depends on whether the json serializer honors the order or not

@dmitrybelyakov

This comment has been minimized.

Copy link

dmitrybelyakov commented Mar 13, 2018

I think it is worth revisiting this issue at some point since dicts will be ordered in Python 3.7 and actually somewhat are in 3.6

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment