I am having a hard time preserving the order of keys in a JSON object stored in a Django JSONField. I have tried using a custom encoder and decoder as per the docs, but the JSON object keeps re-ordeing itself:
>>>from models import MyModel
>>>my_dict = {"c": 3, "b": 2, "a": 1}
>>>my_model = MyModel()
>>>my_model.my_field = my_dict
>>>my_model.save()
>>>my_model.refresh_from_db()
>>>my_model.my_field
OrderedDict([('a',1), ('b', 2), ('c', 3)])
I would have expected it to return OrderedDict([('c',3), ('b', 2), ('a', 1)])
.
Here is what I've tried so far:
models.py:
import collections
import json
from django.db import models
class OrderedEncoder(json.JSONEncoder):
def encode(self, o):
if isinstance(o, collections.OrderedDict):
encoded_objs = [
f"{self.encode(k)}: {self.encode(v)}"
for k, v in o.items()
]
return f"{{{','.join(encoded_objs)}}}"
else:
return super().encode(o)
class OrderedDecoder(json.JSONDecoder):
def __init__(self, *args, **kwargs):
default_kwargs = {
"object_pairs_hook": collections.OrderedDict
}
default_kwargs.update(kwargs)
super().__init__(*args, **default_kwargs)
class MyModel(models.Model):
my_field = models.JSONField(encoder=OrderedEncoder, decoder=OrderedDecoder)
Any ideas?
Had the same issue and I did manage to resolve it by. Not sure if it's best approach but it solved my issue being the same that the order of the key-values was different.
models.py:
then in my code where i access
myModel.my_ordereddict_field
I get the correct sequence of item.To initialise in code
Then if you check type(my_model.my_ordereddict_field) you have OrderedDict and the sequence is correct