Skip to content

Commit f9f320f

Browse files
authored
Improve performance of legacy AT UIDReferenceField's getter (#2212)
* Improve performance of legacy AT `UIDReferenceField`'s getter * Better comment * Better commment * Remove unnecessary code * Keep the order of references * Check by instance instead of multiValue * Rely on UID catalog instead of validating UIDs beforehand
1 parent 763919d commit f9f320f

File tree

2 files changed

+21
-11
lines changed

2 files changed

+21
-11
lines changed

CHANGES.rst

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ Changelog
44
2.4.0 (unreleased)
55
------------------
66

7+
- #2212 Improve performance of legacy AT `UIDReferenceField`'s getter
78
- #2211 Remove `Profile` field (stale) from AnalysisRequest
89
- #2207 Support for file upload on analysis (pre) conditions
910
- #2208 Remove `default_method` from AnalysisRequest's Contact field

src/bika/lims/browser/fields/uidreferencefield.py

+20-11
Original file line numberDiff line numberDiff line change
@@ -155,18 +155,27 @@ def get(self, context, **kwargs):
155155
:return: object or list of objects for multiValued fields.
156156
:rtype: BaseContent | list[BaseContent]
157157
"""
158-
value = StringField.get(self, context, **kwargs)
159-
if not value:
160-
return [] if self.multiValued else None
158+
uids = StringField.get(self, context, **kwargs)
159+
if not isinstance(uids, list):
160+
uids = [uids]
161+
162+
# Do a direct search for all brains at once
163+
uc = api.get_tool("uid_catalog")
164+
references = uc(UID=uids)
165+
166+
# Keep the original order of items
167+
references = sorted(references, key=lambda it: uids.index(it.UID))
168+
169+
# Return objects by default
170+
full_objects = kwargs.pop("full_objects", True)
171+
if full_objects:
172+
references = [api.get_object(ref) for ref in references]
173+
161174
if self.multiValued:
162-
# Only return objects which actually exist; this is necessary here
163-
# because there are no HoldingReferences. This opens the
164-
# possibility that deletions leave hanging references.
165-
ret = filter(
166-
lambda x: x, [self.get_object(context, uid) for uid in value])
167-
else:
168-
ret = self.get_object(context, value)
169-
return ret
175+
return references
176+
elif references:
177+
return references[0]
178+
return None
170179

171180
@security.public
172181
def getRaw(self, context, aslist=False, **kwargs):

0 commit comments

Comments
 (0)