@@ -333,16 +333,28 @@ def unapply(self) -> None:
333
333
affected_deltas = self .delta_urls .all ()
334
334
affected_curated = self .curated_urls .all ()
335
335
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
+
336
340
# Process each affected delta URL
337
341
for delta in affected_deltas :
338
342
curated = CuratedUrl .objects .filter (collection = self .collection , url = delta .url ).first ()
339
343
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 ())
343
355
delta .save ()
344
- else :
345
- # Scenario 2: Both exist
356
+ elif curated :
357
+ # No other patterns match, revert to curated value
346
358
setattr (delta , field , getattr (curated , field ))
347
359
delta .save ()
348
360
@@ -354,17 +366,36 @@ def unapply(self) -> None:
354
366
)
355
367
if fields_match :
356
368
delta .delete ()
369
+ else :
370
+ # No curated URL or other patterns, set to None
371
+ setattr (delta , field , None )
372
+ delta .save ()
357
373
358
374
# Handle curated URLs that don't have deltas
359
375
for curated in affected_curated :
360
376
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 )
368
399
369
400
# Clear pattern relationships
370
401
self .delta_urls .clear ()
0 commit comments