Skip to content

Commit 9c3cc57

Browse files
committed
cleanup
1 parent e47d6c7 commit 9c3cc57

File tree

1 file changed

+19
-51
lines changed

1 file changed

+19
-51
lines changed

backend/proteins/models/fluorophore.py

Lines changed: 19 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from __future__ import annotations
22

3-
from typing import TYPE_CHECKING, Final
3+
from typing import TYPE_CHECKING, Final, cast
44

55
from django.db import models
66
from django.utils.text import slugify
@@ -134,81 +134,49 @@ def rebuild_attributes(self) -> None:
134134
3. Primary reference - Measurement from the owner's primary_reference
135135
4. Most recent - Fallback by date_measured (most recent first)
136136
"""
137-
from proteins.models import FluorescenceMeasurement
138-
139137
measurable_fields = AbstractFluorescenceData.get_measurable_fields()
140138
new_values: dict[str, object] = {}
141139
new_source_map: dict[str, int] = {}
142-
143-
# Get primary reference ID for priority sorting
144140
primary_ref_id = self._get_primary_reference_id()
145141

146-
# 1. Handle pinned fields first (admin overrides)
142+
# Fetch pinned measurements in one query
143+
pinned_source_map = cast("dict[str, int]", self.pinned_source_map)
144+
pinned_by_id = {m.id: m for m in self.measurements.filter(id__in=pinned_source_map.values())}
145+
146+
# Handle pinned fields first (admin overrides)
147147
pinned_fields: set[str] = set()
148-
for field, measurement_id in self.pinned_source_map.items():
149-
if field not in measurable_fields:
150-
continue
151-
try:
152-
measurement = FluorescenceMeasurement.objects.get(id=measurement_id, fluorophore=self)
153-
val = getattr(measurement, field)
154-
if val is not None:
148+
for field, mid in pinned_source_map.items():
149+
if field in measurable_fields and (m := pinned_by_id.get(mid)):
150+
if (val := getattr(m, field)) is not None:
155151
new_values[field] = val
156-
new_source_map[field] = measurement.id
152+
new_source_map[field] = m.id
157153
pinned_fields.add(field)
158-
except FluorescenceMeasurement.DoesNotExist:
159-
# Pinned measurement no longer exists, skip it
160-
pass
161-
162-
# 2. Fetch all measurements for non-pinned fields
163-
measurements = list(self.measurements.select_related("reference").all())
164154

165155
# Sort by priority: trusted > primary_reference > most recent date
166-
def measurement_priority(m: FluorescenceMeasurement) -> tuple[int, int, str]:
167-
# Lower tuple = higher priority (sorted ascending)
168-
trusted_score = 0 if m.is_trusted else 1
169-
primary_score = 0 if primary_ref_id and m.reference_id == primary_ref_id else 1
170-
# Use date_measured for sorting, fallback to empty string (sorts last)
171-
date_str = m.date_measured.isoformat() if m.date_measured else ""
172-
# Negate by reversing string comparison for descending date order
173-
return (trusted_score, primary_score, date_str)
174-
175-
# Sort: trusted first, then primary ref, then most recent date
176-
measurements.sort(key=measurement_priority)
177-
# Reverse date sorting within groups (we want most recent first)
178-
# Re-sort with proper date handling
179-
measurements.sort(
156+
measurements = sorted(
157+
self.measurements.all(),
180158
key=lambda m: (
181-
0 if m.is_trusted else 1,
182-
0 if primary_ref_id and m.reference_id == primary_ref_id else 1,
183-
# Invert date for descending order (most recent first)
159+
not m.is_trusted,
160+
not (primary_ref_id and m.reference_id == primary_ref_id),
184161
-(m.date_measured.toordinal() if m.date_measured else 0),
185-
)
162+
),
186163
)
187164

188-
# 3. Waterfall Logic: Find the first non-null value for each non-pinned field
165+
# Waterfall: first non-null value for each non-pinned field
189166
for field in measurable_fields:
190167
if field in pinned_fields:
191-
continue # Already handled above
192-
168+
continue
193169
for m in measurements:
194-
val = getattr(m, field)
195-
if val is not None:
170+
if (val := getattr(m, field)) is not None:
196171
new_values[field] = val
197172
new_source_map[field] = m.id
198173
break
199174
else:
200-
# No measurement had a value for this field
201-
# Use field default for non-nullable fields (e.g., is_dark)
202175
field_obj = self._meta.get_field(field)
203-
if field_obj.has_default():
204-
new_values[field] = field_obj.get_default()
205-
else:
206-
new_values[field] = None
176+
new_values[field] = field_obj.get_default() if field_obj.has_default() else None
207177

208-
# 4. Update cached values
209178
for key, val in new_values.items():
210179
setattr(self, key, val)
211-
212180
self.source_map = new_source_map
213181
self.save()
214182

0 commit comments

Comments
 (0)