django-bulk-hooks 0.1.222__tar.gz → 0.1.224__tar.gz
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.
- {django_bulk_hooks-0.1.222 → django_bulk_hooks-0.1.224}/PKG-INFO +1 -1
- {django_bulk_hooks-0.1.222 → django_bulk_hooks-0.1.224}/django_bulk_hooks/queryset.py +51 -38
- {django_bulk_hooks-0.1.222 → django_bulk_hooks-0.1.224}/pyproject.toml +1 -1
- {django_bulk_hooks-0.1.222 → django_bulk_hooks-0.1.224}/LICENSE +0 -0
- {django_bulk_hooks-0.1.222 → django_bulk_hooks-0.1.224}/README.md +0 -0
- {django_bulk_hooks-0.1.222 → django_bulk_hooks-0.1.224}/django_bulk_hooks/__init__.py +0 -0
- {django_bulk_hooks-0.1.222 → django_bulk_hooks-0.1.224}/django_bulk_hooks/conditions.py +0 -0
- {django_bulk_hooks-0.1.222 → django_bulk_hooks-0.1.224}/django_bulk_hooks/constants.py +0 -0
- {django_bulk_hooks-0.1.222 → django_bulk_hooks-0.1.224}/django_bulk_hooks/context.py +0 -0
- {django_bulk_hooks-0.1.222 → django_bulk_hooks-0.1.224}/django_bulk_hooks/decorators.py +0 -0
- {django_bulk_hooks-0.1.222 → django_bulk_hooks-0.1.224}/django_bulk_hooks/engine.py +0 -0
- {django_bulk_hooks-0.1.222 → django_bulk_hooks-0.1.224}/django_bulk_hooks/enums.py +0 -0
- {django_bulk_hooks-0.1.222 → django_bulk_hooks-0.1.224}/django_bulk_hooks/handler.py +0 -0
- {django_bulk_hooks-0.1.222 → django_bulk_hooks-0.1.224}/django_bulk_hooks/manager.py +0 -0
- {django_bulk_hooks-0.1.222 → django_bulk_hooks-0.1.224}/django_bulk_hooks/models.py +0 -0
- {django_bulk_hooks-0.1.222 → django_bulk_hooks-0.1.224}/django_bulk_hooks/priority.py +0 -0
- {django_bulk_hooks-0.1.222 → django_bulk_hooks-0.1.224}/django_bulk_hooks/registry.py +0 -0
|
@@ -76,54 +76,67 @@ class HookQuerySetMixin:
|
|
|
76
76
|
|
|
77
77
|
current_bypass_hooks = get_bypass_hooks()
|
|
78
78
|
|
|
79
|
-
#
|
|
80
|
-
|
|
81
|
-
|
|
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
|
-
#
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
#
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
[tool.poetry]
|
|
2
2
|
name = "django-bulk-hooks"
|
|
3
|
-
version = "0.1.
|
|
3
|
+
version = "0.1.224"
|
|
4
4
|
description = "Hook-style hooks for Django bulk operations like bulk_create and bulk_update."
|
|
5
5
|
authors = ["Konrad Beck <konrad.beck@merchantcapital.co.za>"]
|
|
6
6
|
readme = "README.md"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|