Hi,
I'm using Django 3.2 on Postgres12, and I have a model with a JSONField
which contains a simple dict (actually, a Django formset :-)). I would like
to update just one value in the dict. I can get this to work when the new
value is a hardcoded numeric 333 (quoted, as seems to be needed) like this:
pay_items.update(inputs=JSONBSet('inputs', ['inputs-0-value'],
Value("333"), True))
where JSONBSet is a Func, as indicated below. However, I'd like to actually
compute the value. I've tried a variety of things, without success. Here is
one attempt:
pay_items.update(inputs=JSONBSet('inputs', ['inputs-0-value'],
Cast(F('inputs__inputs-0-value'),
FloatField()) + Value("3"),
True))
This fails like this:
ERROR: function jsonb_set(jsonb, unknown, double precision, boolean) does
not exist at character 42
HINT: No function matches the given name and argument types. You might
need to add explicit type casts.
STATEMENT: UPDATE "paiyroll_payitem" SET "inputs" =
JSONB_SET("paiyroll_payitem"."inputs", '{inputs-0-value}',
(CAST(("paiyroll_payitem"."inputs" -> 'inputs-0-value') AS double
precision) + '3'), true) WHERE "paiyroll_payitem"."id" IN (...))
I've tried all sorts of variants with Cast, ExpressionWrapper and so on to
no avail, so I'd be grateful for any shove in the right direction!
Thanks, Shaheed
Encls: implementation of JSONBSet derived from
https://code.djangoproject.com/ticket/32519 and related threads:
class JSONBSet(Func):
function = 'JSONB_SET'
arity = 4
output_field = CharField()
def __init__(self, field, path, value, create: bool = True):
path = Value('{{{0}}}'.format(','.join(path)))
create = Value(create)
super().__init__(field, path, value, create)
--
You received this message because you are subscribed to the Google Groups
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-users/CAHAc2jcT_k36yc3atyJHj7rHiMf0PnvsEdm6bbT7L%3DhgDpZbyQ%40mail.gmail.com.