Let's say I have a model:
class Foo(Model):
bar = JSONField(...)
I can easily filter by the elements of bar
. For example,
Foo.objects.filter(bar__has_key="some_key").count()
will give me the number of Foo
objects that have "some_key"
as a key in their bar
field.
My question is about updates. I tried:
Foo.objects.exclude(bar__has_key="some_key").update(bar__some_key={"x": "y"})
to set the value to some default where it isn't set, but that gives me
django.core.exceptions.FieldDoesNotExist: Foo has no field named 'bar__some_key'.
I can, of course, do
objs = list(Foo.objects.exclude(bar__has_key="some_key"))
for obj in objs:
obj.bar["some_key"] = {"x": "y"}
Foo.objects.bulk_update(objs, ["bar"])
but I'm interested if this can be done without looping (and generating potentially large Foo
objects in memory), using only QuerySet.update
.
Additionally, I'd be curious how to remove "some_key"
from all objects that have it. So, this:
objs = list(Foo.objects.filter(bar__has_key="some_key"))
for obj in objs:
del obj.bar["some_key"]
Foo.objects.bulk_update(objs, ["bar"])
but again using only QuerySet.update
.