diff --git a/docs/changelog.rst b/docs/changelog.rst index e4c5c5e..3359df3 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -15,6 +15,7 @@ Changelog applied. Uninstalling from the same panel removes the PAS plugin and the per-user JWT signing secrets. +- #106 Fix single-valued UID reference fields not settable through the JSON API - #94 Extract registry and settings helpers to api/settings - #93 Convert api module into a package and extract user helpers - #92 Restrict /registry, /settings, /users to prevent info leaks diff --git a/src/senaite/jsonapi/fieldmanagers.py b/src/senaite/jsonapi/fieldmanagers.py index 60223e1..ea5af78 100644 --- a/src/senaite/jsonapi/fieldmanagers.py +++ b/src/senaite/jsonapi/fieldmanagers.py @@ -664,14 +664,18 @@ def set(self, instance, value, **kw): # noqa elif api.is_path(v): refs.append(api.get_object_by_path(v)) - # Handle non multi valued fields + # convert all references to UIDs + refs = [str(api.get_uid(ref)) for ref in refs if ref] + + # Single valued fields expect a scalar value, not a list. Passing a + # list makes the field validator of e.g. an AT UIDReferenceField + # reject the value with "[...] is not supported", so unwrap it here + # (None clears the reference). Multi valued fields keep the list. if not self.multi_valued: if len(refs) > 1: raise ValueError("Multiple values given for single valued " "field {}".format(repr(self.field))) - - # convert all references to UIDs - refs = [str(api.get_uid(ref)) for ref in refs if ref] + refs = refs[0] if refs else None return self._set(instance, refs, **kw)