Let´s say we have a database and there is a json stored as a string which contains configurations. In the application we want to update only a specific value and write then back the json as a string to the database.
The HTTP request provides a "jsonPath" which reflects a path in the json file to navigate to the object we want to update. This parameter is supplied as a list.
An example for the path could be something like ['input', 'keyboard', 'language'] and the value we want to set is 'en'
Here we load the configuration from the database which works so far:
if request.data['jsonPath']:
config = json.loads(models.Config.objects.get(name__startswith='general').value
Then config is just a normal object now, which I can access with the dot notation like config.input.keyboard.language and it contains then the according part in json syntax.
I am able to read out the value of the field with the following syntax:
config[request.data['jsonPath'][0]][request.data['jsonPath'][1]][request.data['jsonPath'[3]]
But the number of parameters can vary and I want also to write it back into the config object, convert it back to a string and write it into the database.
I know it is not a nice thing but I would be interessted how it can be done like this
CodePudding user response:
Assuming you have a nested json object like this:
mydict = {
'key1': {
'key2': {
'key3': {
'foo': 'bar'
},
},
},
}
And you have a "path" list like this:
path = ['key1', 'key2', 'key3']
You can traverse the path like this:
data = mydict
for key in path:
data = data[key]
data
will end up as the value of the last item in path
, in this case the subdict {'foo': 'bar'}
CodePudding user response:
You can use functools.reduce
for this:
functools.reduce(dict.get, path, data)
from functools import reduce
data = {'key1': {'key2': {'key3': {'foo': 'bar'}}}}
path = ['key1', 'key2', 'key3']
reduce(dict.get, path, data)["foo"] = baz
Result:
{'key1': {'key2': {'key3': {'foo': 'baz'}}}}
P.S
If the data type of data
is something else you could possibly use operator.itemgetter