Skip to content

Commit 393402c

Browse files
committed
update Field modifier unapply to handle pattern overlaps
1 parent ec471b0 commit 393402c

File tree

1 file changed

+43
-12
lines changed

1 file changed

+43
-12
lines changed

sde_collections/models/delta_patterns.py

Lines changed: 43 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -333,16 +333,28 @@ def unapply(self) -> None:
333333
affected_deltas = self.delta_urls.all()
334334
affected_curated = self.curated_urls.all()
335335

336+
# Get all other patterns of same type for this collection
337+
pattern_class = self.__class__
338+
other_patterns = pattern_class.objects.filter(collection=self.collection).exclude(id=self.id)
339+
336340
# Process each affected delta URL
337341
for delta in affected_deltas:
338342
curated = CuratedUrl.objects.filter(collection=self.collection, url=delta.url).first()
339343

340-
if not curated:
341-
# Scenario 1: Delta only - new URL
342-
setattr(delta, field, None)
344+
# Find next most specific matching pattern if any
345+
matching_patterns = [p for p in other_patterns if re.search(p.get_regex_pattern(), delta.url)]
346+
347+
next_pattern = None
348+
if matching_patterns:
349+
# Sort by number of URLs matched (ascending) to find most specific
350+
next_pattern = min(matching_patterns, key=lambda p: p.get_url_match_count())
351+
352+
if next_pattern:
353+
# Apply next most specific pattern's value
354+
setattr(delta, field, next_pattern.get_new_value())
343355
delta.save()
344-
else:
345-
# Scenario 2: Both exist
356+
elif curated:
357+
# No other patterns match, revert to curated value
346358
setattr(delta, field, getattr(curated, field))
347359
delta.save()
348360

@@ -354,17 +366,36 @@ def unapply(self) -> None:
354366
)
355367
if fields_match:
356368
delta.delete()
369+
else:
370+
# No curated URL or other patterns, set to None
371+
setattr(delta, field, None)
372+
delta.save()
357373

358374
# Handle curated URLs that don't have deltas
359375
for curated in affected_curated:
360376
if not DeltaUrl.objects.filter(url=curated.url).exists():
361-
# Scenario 3: Curated only
362-
# Copy all fields from curated except the one we're nulling
363-
fields = {
364-
f.name: getattr(curated, f.name) for f in curated._meta.fields if f.name not in ["id", "collection"]
365-
}
366-
fields[field] = None # Set the pattern's field to None
367-
delta = DeltaUrl.objects.create(collection=self.collection, **fields)
377+
# Find any matching patterns
378+
matching_patterns = [p for p in other_patterns if re.search(p.get_regex_pattern(), curated.url)]
379+
380+
if matching_patterns:
381+
# Apply most specific pattern's value
382+
next_pattern = min(matching_patterns, key=lambda p: p.get_url_match_count())
383+
fields = {
384+
f.name: getattr(curated, f.name)
385+
for f in curated._meta.fields
386+
if f.name not in ["id", "collection"]
387+
}
388+
fields[field] = next_pattern.get_new_value()
389+
DeltaUrl.objects.create(collection=self.collection, **fields)
390+
else:
391+
# No other patterns, create delta with None
392+
fields = {
393+
f.name: getattr(curated, f.name)
394+
for f in curated._meta.fields
395+
if f.name not in ["id", "collection"]
396+
}
397+
fields[field] = None
398+
DeltaUrl.objects.create(collection=self.collection, **fields)
368399

369400
# Clear pattern relationships
370401
self.delta_urls.clear()

0 commit comments

Comments
 (0)