Home >Backend Development >Python Tutorial >How to update the values of multiple keys in a JsonField using the .update() method using Django's ORM?
I have a model field that I'm trying to update using django's .update()
method. The field is a jsonfield. I usually keep a dictionary in this area. For example{"test": "Yes", "prod": "No"}
This is the model:
class question(models.model): # {"test": "yes", "prod": "no"} extra_data = models.jsonfield(default=dict, null=true, blank=true)
I can update the keys within the dictionary using this query (which works great, btw):
Question.filter(id="123").update(meta_data=Func( F("extra_data"), Value(["test"]), Value("no", JSONField()), function="jsonb_set", ))
Now the question is, is there a way to update multiple keys (in my case two) at once using .update()
as shown in the above query?
I want to achieve this using the .update()
method instead of .save()
so that I can avoid calling the post_save signal function.
Disclaimer: It will look ugly.
I've done this in the past, albeit using pure sql, not django. The idea is to call jsonb_set()
recursively. Each call sets a key.
So, in sql, to set the key {"test":"yes","prod":"no"}
You can do this:
update question set meta_data = jsonb_set(jsonb_set(extra_data, '{test}', '"yes"'::jsonb), '{prod}', '"no"'::jsonb) where id = 123;
Please note that jsonb_set has two nested calls, the innermost one uses meta_data
, and the outermost one receives the innermost result.
So the django equivalent would look like this (note, untested):
question.filter(id="123").update( meta_data=func( func( f("extra_data"), value(["test"]), value("yes", jsonfield()), function="jsonb_set", ), value(["prod"]), value("no", jsonfield()), function="jsonb_set", ))
Or you can create a recursive function that returns the mess for you, setting one item at a time:
def recursive_jsonb_set(original, **kwargs): if kwargs: key, value = kwargs.popitem() return Func( recursive_jsonb_set(original, **kwargs), Value(key.split('__')), Value(value, JSONField()), function="jsonb_set") else: return original Question.filter(id="123").update( meta_data=recursive_jsonb_set(F("extra_data"), test="yes", prod="no", other__status="done"))
Please note the '__'
function to update subkeys.
The above is the detailed content of How to update the values of multiple keys in a JsonField using the .update() method using Django's ORM?. For more information, please follow other related articles on the PHP Chinese website!