django-bulk-hooks 0.1.225__py3-none-any.whl → 0.1.226__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of django-bulk-hooks might be problematic. Click here for more details.

@@ -68,6 +68,7 @@ class HookModelMixin(models.Model):
68
68
  logger.debug(f"save() creating new {self.__class__.__name__} instance")
69
69
  # For create operations, we don't have old records
70
70
  ctx = HookContext(self.__class__)
71
+ run(self.__class__, VALIDATE_CREATE, [self], ctx=ctx)
71
72
  run(self.__class__, BEFORE_CREATE, [self], ctx=ctx)
72
73
 
73
74
  super().save(*args, **kwargs)
@@ -80,6 +81,7 @@ class HookModelMixin(models.Model):
80
81
  # Use _base_manager to avoid triggering hooks recursively
81
82
  old_instance = self.__class__._base_manager.get(pk=self.pk)
82
83
  ctx = HookContext(self.__class__)
84
+ run(self.__class__, VALIDATE_UPDATE, [self], [old_instance], ctx=ctx)
83
85
  run(self.__class__, BEFORE_UPDATE, [self], [old_instance], ctx=ctx)
84
86
 
85
87
  super().save(*args, **kwargs)
@@ -88,6 +90,7 @@ class HookModelMixin(models.Model):
88
90
  except self.__class__.DoesNotExist:
89
91
  # If the old instance doesn't exist, treat as create
90
92
  ctx = HookContext(self.__class__)
93
+ run(self.__class__, VALIDATE_CREATE, [self], ctx=ctx)
91
94
  run(self.__class__, BEFORE_CREATE, [self], ctx=ctx)
92
95
 
93
96
  super().save(*args, **kwargs)
@@ -65,11 +65,27 @@ class HookQuerySetMixin:
65
65
  }
66
66
  originals = [original_map.get(obj.pk) for obj in instances]
67
67
 
68
- # Check if any of the update values are Subquery objects
68
+ # Check if any of the update values are complex database expressions (Subquery, Case, etc.)
69
69
  has_subquery = any(
70
- hasattr(value, "query") and hasattr(value, "resolve_expression")
70
+ (hasattr(value, "query") and hasattr(value, "resolve_expression"))
71
+ or hasattr(
72
+ value, "resolve_expression"
73
+ ) # This catches Case, F expressions, etc.
71
74
  for value in kwargs.values()
72
75
  )
76
+
77
+ # Also check if any of the instances have complex expressions in their attributes
78
+ # This can happen when bulk_update creates Case expressions and applies them to instances
79
+ if not has_subquery and instances:
80
+ for instance in instances:
81
+ for field_name in kwargs.keys():
82
+ if hasattr(instance, field_name):
83
+ field_value = getattr(instance, field_name)
84
+ if hasattr(field_value, "resolve_expression"):
85
+ has_subquery = True
86
+ break
87
+ if has_subquery:
88
+ break
73
89
 
74
90
  # Check if we're in a bulk operation context to prevent double hook execution
75
91
  from django_bulk_hooks.context import get_bypass_hooks
@@ -98,11 +114,11 @@ class HookQuerySetMixin:
98
114
  engine.run(
99
115
  model_cls, VALIDATE_UPDATE, instances, originals, ctx=ctx
100
116
  )
101
- except (TypeError, ValueError) as e:
102
- # If validation fails due to Subquery comparison, skip validation for subquery updates
103
- # This is a limitation - validation hooks cannot easily work with unresolved subqueries
117
+ except (TypeError, ValueError, AttributeError) as e:
118
+ # If validation fails due to Subquery/Case comparison, skip validation for complex updates
119
+ # This is a limitation - validation hooks cannot easily work with unresolved database expressions
104
120
  logger.warning(
105
- f"Skipping validation hooks for subquery update due to: {e}"
121
+ f"Skipping validation hooks for complex update due to: {e}"
106
122
  )
107
123
 
108
124
  # Execute the database update first to compute subquery values
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: django-bulk-hooks
3
- Version: 0.1.225
3
+ Version: 0.1.226
4
4
  Summary: Hook-style hooks for Django bulk operations like bulk_create and bulk_update.
5
5
  Home-page: https://github.com/AugendLimited/django-bulk-hooks
6
6
  License: MIT
@@ -7,11 +7,11 @@ django_bulk_hooks/engine.py,sha256=t_kvgex6_iZEFc5LK-srBTZPe-1bdlYdip5LfWOc6lc,2
7
7
  django_bulk_hooks/enums.py,sha256=Zo8_tJzuzZ2IKfVc7gZ-0tWPT8q1QhqZbAyoh9ZVJbs,381
8
8
  django_bulk_hooks/handler.py,sha256=xZt8iNdYF-ACz-MnKMY0co6scWINU5V5wC1lyDn844k,4854
9
9
  django_bulk_hooks/manager.py,sha256=nfWiwU5-yAoxdnQsUMohxtyCpkV0MBv6X3wmipr9eQY,3697
10
- django_bulk_hooks/models.py,sha256=exnXYVKEVbYAXhChCP8VdWTnKCnm9DiTcokEIBee1I0,4350
10
+ django_bulk_hooks/models.py,sha256=mj4f93L64CN1XBS29RlS02WnZjCNoUkai97vKqjgZQ8,4575
11
11
  django_bulk_hooks/priority.py,sha256=HG_2D35nga68lBCZmSXTcplXrjFoRgZFRDOy4ROKonY,376
12
- django_bulk_hooks/queryset.py,sha256=Uq6mBQOrShe6Ahvh5tdItJOmVkhZi4Ndyva1aqKal88,33895
12
+ django_bulk_hooks/queryset.py,sha256=1Tb-mXHNqzsrcDFU6YURooT1aHNpb56oFGF1ndBaXnw,34763
13
13
  django_bulk_hooks/registry.py,sha256=8UuhniiH5ChSeOKV1UUbqTEiIu25bZXvcHmkaRbxmME,1131
14
- django_bulk_hooks-0.1.225.dist-info/LICENSE,sha256=dguKIcbDGeZD-vXWdLyErPUALYOvtX_fO4Zjhq481uk,1088
15
- django_bulk_hooks-0.1.225.dist-info/METADATA,sha256=5b8WTSqOjYEqljpLICZ42_N8Gj0TkwNBbv220Uh7q54,9049
16
- django_bulk_hooks-0.1.225.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
17
- django_bulk_hooks-0.1.225.dist-info/RECORD,,
14
+ django_bulk_hooks-0.1.226.dist-info/LICENSE,sha256=dguKIcbDGeZD-vXWdLyErPUALYOvtX_fO4Zjhq481uk,1088
15
+ django_bulk_hooks-0.1.226.dist-info/METADATA,sha256=9szvW2lyMJr2LMSqDQu32TtD8TKbUgPQ-GsaU-t0jnI,9049
16
+ django_bulk_hooks-0.1.226.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
17
+ django_bulk_hooks-0.1.226.dist-info/RECORD,,