django-bulk-hooks 0.1.222__py3-none-any.whl → 0.1.223__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.

@@ -76,54 +76,67 @@ class HookQuerySetMixin:
76
76
 
77
77
  current_bypass_hooks = get_bypass_hooks()
78
78
 
79
- # If we used Subquery objects, we need to resolve them before hooks to avoid comparison errors
80
- if has_subquery and not current_bypass_hooks:
81
- # Execute the Django update first to compute subquery values
79
+ # Apply field updates to instances for all cases (needed for hook inspection)
80
+ for obj in instances:
81
+ for field, value in kwargs.items():
82
+ # For subquery fields, set the original Subquery object temporarily
83
+ # We'll resolve it after database update if needed
84
+ setattr(obj, field, value)
85
+
86
+ # If we're in a bulk operation context, skip hooks to prevent double execution
87
+ if current_bypass_hooks:
88
+ ctx = HookContext(model_cls, bypass_hooks=True)
89
+ # For bulk operations without hooks, execute update
82
90
  update_count = super().update(**kwargs)
91
+ else:
92
+ ctx = HookContext(model_cls, bypass_hooks=False)
83
93
 
84
- # Refresh instances to get computed subquery values BEFORE running hooks
85
- refreshed_instances = {
86
- obj.pk: obj for obj in model_cls._base_manager.filter(pk__in=pks)
87
- }
88
-
89
- # Update instances in memory with computed values
90
- for instance in instances:
91
- if instance.pk in refreshed_instances:
92
- refreshed_instance = refreshed_instances[instance.pk]
93
- # Update all fields except primary key with the computed values
94
- for field in model_cls._meta.fields:
95
- if field.name != "id":
96
- setattr(
97
- instance,
98
- field.name,
99
- getattr(refreshed_instance, field.name),
100
- )
94
+ # For subquery cases, we need special handling
95
+ if has_subquery:
96
+ # Run validation hooks first with Subquery objects (if validation doesn't access them)
97
+ try:
98
+ engine.run(
99
+ model_cls, VALIDATE_UPDATE, instances, originals, ctx=ctx
100
+ )
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
104
+ logger.warning(
105
+ f"Skipping validation hooks for subquery update due to: {e}"
106
+ )
101
107
 
102
- # Now run hooks with resolved subquery values
103
- ctx = HookContext(model_cls, bypass_hooks=False)
104
- # Run validation hooks first
105
- engine.run(model_cls, VALIDATE_UPDATE, instances, originals, ctx=ctx)
106
- # Then run BEFORE_UPDATE hooks
107
- engine.run(model_cls, BEFORE_UPDATE, instances, originals, ctx=ctx)
108
- else:
109
- # Apply field updates to instances for non-subquery cases
110
- for obj in instances:
111
- for field, value in kwargs.items():
112
- setattr(obj, field, value)
113
-
114
- # If we're in a bulk operation context, skip hooks to prevent double execution
115
- if current_bypass_hooks:
116
- ctx = HookContext(model_cls, bypass_hooks=True)
117
- # For bulk operations without hooks, execute Django update if not done already
108
+ # Execute the database update first to compute subquery values
118
109
  update_count = super().update(**kwargs)
110
+
111
+ # Refresh instances to get computed subquery values BEFORE running BEFORE hooks
112
+ refreshed_instances = {
113
+ obj.pk: obj for obj in model_cls._base_manager.filter(pk__in=pks)
114
+ }
115
+
116
+ # Update instances in memory with computed values
117
+ for instance in instances:
118
+ if instance.pk in refreshed_instances:
119
+ refreshed_instance = refreshed_instances[instance.pk]
120
+ # Update all fields except primary key with the computed values
121
+ for field in model_cls._meta.fields:
122
+ if field.name != "id":
123
+ setattr(
124
+ instance,
125
+ field.name,
126
+ getattr(refreshed_instance, field.name),
127
+ )
128
+
129
+ # Now run BEFORE_UPDATE hooks with resolved values
130
+ # Note: This is a trade-off - BEFORE hooks run after DB update for subquery cases
131
+ engine.run(model_cls, BEFORE_UPDATE, instances, originals, ctx=ctx)
119
132
  else:
120
- ctx = HookContext(model_cls, bypass_hooks=False)
133
+ # Normal case without subqueries - run hooks in proper order
121
134
  # Run validation hooks first
122
135
  engine.run(model_cls, VALIDATE_UPDATE, instances, originals, ctx=ctx)
123
136
  # Then run BEFORE_UPDATE hooks
124
137
  engine.run(model_cls, BEFORE_UPDATE, instances, originals, ctx=ctx)
125
138
 
126
- # Execute Django update if not done already (for non-subquery cases)
139
+ # Execute update
127
140
  update_count = super().update(**kwargs)
128
141
 
129
142
  # Run AFTER_UPDATE hooks only for standalone updates
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: django-bulk-hooks
3
- Version: 0.1.222
3
+ Version: 0.1.223
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
@@ -9,9 +9,9 @@ django_bulk_hooks/handler.py,sha256=xZt8iNdYF-ACz-MnKMY0co6scWINU5V5wC1lyDn844k,
9
9
  django_bulk_hooks/manager.py,sha256=nfWiwU5-yAoxdnQsUMohxtyCpkV0MBv6X3wmipr9eQY,3697
10
10
  django_bulk_hooks/models.py,sha256=exnXYVKEVbYAXhChCP8VdWTnKCnm9DiTcokEIBee1I0,4350
11
11
  django_bulk_hooks/priority.py,sha256=HG_2D35nga68lBCZmSXTcplXrjFoRgZFRDOy4ROKonY,376
12
- django_bulk_hooks/queryset.py,sha256=INcmUxugAxDY8M2Swvv4lItyniejT1CNUpJtEnFfoBw,33087
12
+ django_bulk_hooks/queryset.py,sha256=ZEYrO8AJunmoS9n7xSkjDTG3kOAntAOTnpfsd-GhC0c,33798
13
13
  django_bulk_hooks/registry.py,sha256=8UuhniiH5ChSeOKV1UUbqTEiIu25bZXvcHmkaRbxmME,1131
14
- django_bulk_hooks-0.1.222.dist-info/LICENSE,sha256=dguKIcbDGeZD-vXWdLyErPUALYOvtX_fO4Zjhq481uk,1088
15
- django_bulk_hooks-0.1.222.dist-info/METADATA,sha256=QJazHusCLVY-qjWHDauyE9KUPPsnvGOLTd6ral0T9Wc,9049
16
- django_bulk_hooks-0.1.222.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
17
- django_bulk_hooks-0.1.222.dist-info/RECORD,,
14
+ django_bulk_hooks-0.1.223.dist-info/LICENSE,sha256=dguKIcbDGeZD-vXWdLyErPUALYOvtX_fO4Zjhq481uk,1088
15
+ django_bulk_hooks-0.1.223.dist-info/METADATA,sha256=IW85vPi4EzF2Z3NrWrlZri4Ps65WGsITEvhbfcbZdWw,9049
16
+ django_bulk_hooks-0.1.223.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
17
+ django_bulk_hooks-0.1.223.dist-info/RECORD,,