From 60e943054257e462906a440ed71b035e4af99831 Mon Sep 17 00:00:00 2001 From: mpeltriaux Date: Wed, 14 Jan 2026 09:02:41 +0100 Subject: [PATCH] # Boost geometry conflict message fetch * reduces runtime of geometry conflict info message generating to ~45% to prior runtime --- konova/models/geometry.py | 16 ++++++++++++---- konova/models/object.py | 12 ++++++++---- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/konova/models/geometry.py b/konova/models/geometry.py index 280e3a11..9e211b3c 100644 --- a/konova/models/geometry.py +++ b/konova/models/geometry.py @@ -103,9 +103,12 @@ class Geometry(BaseResource): resolved_conflicts = all_conflicted_by_conflicts.exclude(id__in=still_conflicting_conflicts) resolved_conflicts.delete() - def get_data_objects(self): + def get_data_objects(self, limit_to_attrs: list = None): """ Getter for all objects which are related to this geometry + Using the limit_to_attrs we can limit the amount of returned data directly onto the data object attributes + we want to have. Reduces memory consumption and runtime. + Returns: objs (list): The list of objects """ @@ -121,15 +124,20 @@ class Geometry(BaseResource): set_objs = _set.filter( deleted=None ) - objs += set_objs + if limit_to_attrs: + objs += set_objs.values_list(*limit_to_attrs, flat=True) + else: + objs += set_objs # ... but we need a special treatment for compensations, since they can be deleted directly OR inherit their # de-facto-deleted status from their deleted parent intervention comp_objs = self.compensation_set.filter( Q(deleted=None) & Q(intervention__deleted=None) ) - objs += comp_objs - + if limit_to_attrs: + objs += comp_objs.values_list(*limit_to_attrs, flat=True) + else: + objs += comp_objs return objs def get_data_object(self): diff --git a/konova/models/object.py b/konova/models/object.py index 573dbf8c..7faa0c4d 100644 --- a/konova/models/object.py +++ b/konova/models/object.py @@ -677,19 +677,23 @@ class GeoReferencedMixin(models.Model): return request instance_objs = [] + needed_data_object_attrs = [ + "identifier" + ] conflicts = self.geometry.conflicts_geometries.iterator() for conflict in conflicts: - instance_objs += conflict.affected_geometry.get_data_objects() + # Only check the affected geometry of this conflict, since we know the conflicting geometry is self.geometry + instance_objs += conflict.affected_geometry.get_data_objects(needed_data_object_attrs) conflicts = self.geometry.conflicted_by_geometries.iterator() for conflict in conflicts: - instance_objs += conflict.conflicting_geometry.get_data_objects() + # Only check the conflicting geometry of this conflict, since we know the affected geometry is self.geometry + instance_objs += conflict.conflicting_geometry.get_data_objects(needed_data_object_attrs) add_message = len(instance_objs) > 0 if add_message: - instance_identifiers = [x.identifier for x in instance_objs] - instance_identifiers = ", ".join(instance_identifiers) + instance_identifiers = ", ".join(instance_objs) message_str = GEOMETRY_CONFLICT_WITH_TEMPLATE.format(instance_identifiers) messages.info(request, message_str) return request -- 2.49.1