Django ORM - call queryset update() in json field when the key to update is not present
2022-05-31
PostgresDjango
2022-05-31
I learnt today that this is not possible with the Django ORM to call update in a queryset json field when the key that you want to update is not present. For example:
queryset.update(json_data__key="something")
This will return FieldDoesNotExist: ModelClass has no field named 'json_data__key'
because some objects does not have the key “key”.
I found in this stackoverflow post a great solution for this.
from django.db.models.expressions import Func
class JsonSetValue(Func):
function = "jsonb_set"
template = "%(function)s(%(expressions)s, '{\"%(keyname)s\"}','\"%(new_value)s\"', %(create_missing)s)"
arity = 1
def __init__(
self,
expression: str,
keyname: str,
new_value: str,
create_missing: bool = False,
**extra,
):
super().__init__(
expression,
keyname=keyname,
new_value=new_value,
create_missing="true" if create_missing else "false",
**extra,
)
With help of JsonSetValue
you will be able to do the following:
queryset.update(
json_data=JsonSetValue(
"json_data",
keyname="key",
new_value="something",
create_missing=True,
)
)