Repository navigation
Fix single-valued UID reference fields not settable through the JSON API - #106
Merged
Merged
Conversation
The UIDReferenceFieldMixin always passed a list to the field setter, even
for single-valued fields. AT UIDReferenceField validators reject a list
value ('[...] is not supported'), so assigning e.g. a Sample's
Specification, Batch or SamplePoint through the API failed. Unwrap the
list to a scalar (or None to clear) for non multi-valued fields, matching
the classic ReferenceFieldManager.
xispa
approved these changes
Oct 6, 2026
This was referenced Oct 6, 2026
ramonski
added a commit
that referenced
this pull request
Oct 7, 2026
Two separate faults, both of which end as a WrongContainedType or a WrongType on a field the request never mentions. #106 unwrapped a single valued reference from its list to a bare UID. An Archetypes UIDReferenceField needs that, and refuses a list with "[...] is not supported". A Dexterity UIDReferenceField derives from zope.schema List and validates as one, so the bare UID fails before it is ever stored, and setting e.g. a department's manager through the API stopped working. The unwrapping moves to the Archetypes field manager, through a to_field_value hook, so each side is handed the shape its own validator expects. The second fault is older and was hiding behind the first. A Dexterity type migrated from Archetypes keeps the old capitalised name as a BBB property, and a payload written against the old API uses it. get_field looked the name up exactly, so the schema field was not found and the data manager fell back to the BBB setter. Some of those setters convert the value, and many hand it to the mutator as it came: a duration stays the mapping JSON carried, a UID stays unicode. The schema spellings are tried after the exact name, and only a candidate naming a real field is used. There are 140 of these BBB properties on Dexterity content, and 112 of them name a schema field. Lowering the first letter reaches 43; the rest are snake case. A few keep neither convention (a sample template calls its field `samplepoint`), which is why the plain lower case form is tried too. The new doctest covers both faults, and fails if either fix is reverted.
ramonski
added a commit
that referenced
this pull request
Oct 7, 2026
Two separate faults, both of which end as a WrongContainedType or a WrongType on a field the request never mentions. #106 unwrapped a single valued reference from its list to a bare UID. An Archetypes UIDReferenceField needs that, and refuses a list with "[...] is not supported". A Dexterity UIDReferenceField derives from zope.schema List and validates as one, so the bare UID fails before it is ever stored, and setting e.g. a department's manager through the API stopped working. The unwrapping moves to the Archetypes field manager, through a to_field_value hook, so each side is handed the shape its own validator expects. The second fault is older and was hiding behind the first. A Dexterity type migrated from Archetypes keeps the old capitalised name as a BBB property, and a payload written against the old API uses it. get_field looked the name up exactly, so the schema field was not found and the data manager fell back to the BBB setter. Some of those setters convert the value, and many hand it to the mutator as it came: a duration stays the mapping JSON carried, a UID stays unicode. The schema spellings are tried after the exact name, and only a candidate naming a real field is used. There are 140 of these BBB properties on Dexterity content, and 112 of them name a schema field. Lowering the first letter reaches 43; the rest are snake case. A few keep neither convention (a sample template calls its field `samplepoint`), which is why the plain lower case form is tried too. The new doctest covers both faults, and fails if either fix is reverted.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description of the issue/feature this PR addresses
UIDReferenceFieldMixin.setalways forwards the resolved references to the field setter as a list, even when the field is single-valued. ATUIDReferenceFieldvalidators reject a list value with[...] is not supported, so assigning a single-valued reference through@@API/senaite/v1/update(orcreate) fails — for example a Sample'sSpecification,Batch,SamplePointorTemplate.The classic
ReferenceFieldManageralready unwraps single-valued fields to a scalar; the UID reference mixin (used by both the AT and DX UID reference field managers) does not.Current behavior before PR
Updating a single-valued UID reference field fails:
The same happens with
{"Specification": {"uid": "<spec-uid>"}}, because the value still reaches the field validator wrapped in a list.Desired behavior after PR is merged
The reference is assigned. Non multi-valued fields receive a scalar UID (or
Noneto clear); multi-valued fields keep the list, unchanged. DXUIDReferenceField.setalready normalizes viato_list, so scalars are accepted there too — the change is safe for both field managers.--
Reproduced against a live 2.x instance (assigning a Sample
Specification). The fix mirrors the single-valued handling inReferenceFieldManager.I confirm I have coded it according to PEP8 standards.