django-bulk-hooks 0.1.218__tar.gz → 0.1.219__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.218 → django_bulk_hooks-0.1.219}/PKG-INFO +1 -1
- {django_bulk_hooks-0.1.218 → django_bulk_hooks-0.1.219}/django_bulk_hooks/engine.py +5 -5
- {django_bulk_hooks-0.1.218 → django_bulk_hooks-0.1.219}/django_bulk_hooks/queryset.py +15 -12
- {django_bulk_hooks-0.1.218 → django_bulk_hooks-0.1.219}/django_bulk_hooks/registry.py +2 -2
- {django_bulk_hooks-0.1.218 → django_bulk_hooks-0.1.219}/pyproject.toml +1 -1
- {django_bulk_hooks-0.1.218 → django_bulk_hooks-0.1.219}/LICENSE +0 -0
- {django_bulk_hooks-0.1.218 → django_bulk_hooks-0.1.219}/README.md +0 -0
- {django_bulk_hooks-0.1.218 → django_bulk_hooks-0.1.219}/django_bulk_hooks/__init__.py +0 -0
- {django_bulk_hooks-0.1.218 → django_bulk_hooks-0.1.219}/django_bulk_hooks/conditions.py +0 -0
- {django_bulk_hooks-0.1.218 → django_bulk_hooks-0.1.219}/django_bulk_hooks/constants.py +0 -0
- {django_bulk_hooks-0.1.218 → django_bulk_hooks-0.1.219}/django_bulk_hooks/context.py +0 -0
- {django_bulk_hooks-0.1.218 → django_bulk_hooks-0.1.219}/django_bulk_hooks/decorators.py +0 -0
- {django_bulk_hooks-0.1.218 → django_bulk_hooks-0.1.219}/django_bulk_hooks/enums.py +0 -0
- {django_bulk_hooks-0.1.218 → django_bulk_hooks-0.1.219}/django_bulk_hooks/handler.py +0 -0
- {django_bulk_hooks-0.1.218 → django_bulk_hooks-0.1.219}/django_bulk_hooks/manager.py +0 -0
- {django_bulk_hooks-0.1.218 → django_bulk_hooks-0.1.219}/django_bulk_hooks/models.py +0 -0
- {django_bulk_hooks-0.1.218 → django_bulk_hooks-0.1.219}/django_bulk_hooks/priority.py +0 -0
|
@@ -23,11 +23,11 @@ def run(model_cls, event, new_records, old_records=None, ctx=None):
|
|
|
23
23
|
import traceback
|
|
24
24
|
|
|
25
25
|
stack = traceback.format_stack()
|
|
26
|
-
|
|
26
|
+
logger.debug(f"engine.run {model_cls.__name__}.{event} {len(new_records)} records")
|
|
27
27
|
|
|
28
28
|
# Check if we're in a bypass context
|
|
29
29
|
if ctx and hasattr(ctx, 'bypass_hooks') and ctx.bypass_hooks:
|
|
30
|
-
|
|
30
|
+
logger.debug("engine.run bypassed")
|
|
31
31
|
return
|
|
32
32
|
|
|
33
33
|
# For BEFORE_* events, run model.clean() first for validation
|
|
@@ -41,7 +41,7 @@ def run(model_cls, event, new_records, old_records=None, ctx=None):
|
|
|
41
41
|
|
|
42
42
|
# Process hooks
|
|
43
43
|
for handler_cls, method_name, condition, priority in hooks:
|
|
44
|
-
|
|
44
|
+
logger.debug(f"Processing {handler_cls.__name__}.{method_name}")
|
|
45
45
|
handler_instance = handler_cls()
|
|
46
46
|
func = getattr(handler_instance, method_name)
|
|
47
47
|
|
|
@@ -63,12 +63,12 @@ def run(model_cls, event, new_records, old_records=None, ctx=None):
|
|
|
63
63
|
to_process_old.append(original)
|
|
64
64
|
|
|
65
65
|
if to_process_new:
|
|
66
|
-
|
|
66
|
+
logger.debug(f"Executing {handler_cls.__name__}.{method_name} for {len(to_process_new)} records")
|
|
67
67
|
try:
|
|
68
68
|
func(
|
|
69
69
|
new_records=to_process_new,
|
|
70
70
|
old_records=to_process_old if any(to_process_old) else None,
|
|
71
71
|
)
|
|
72
72
|
except Exception as e:
|
|
73
|
-
|
|
73
|
+
logger.debug(f"Hook execution failed: {e}")
|
|
74
74
|
raise
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
import logging
|
|
1
2
|
from django.db import models, transaction
|
|
2
3
|
from django.db.models import AutoField, Case, Field, Value, When
|
|
3
4
|
|
|
4
5
|
from django_bulk_hooks import engine
|
|
6
|
+
|
|
7
|
+
logger = logging.getLogger(__name__)
|
|
5
8
|
from django_bulk_hooks.constants import (
|
|
6
9
|
AFTER_CREATE,
|
|
7
10
|
AFTER_DELETE,
|
|
@@ -78,10 +81,10 @@ class HookQuerySetMixin:
|
|
|
78
81
|
|
|
79
82
|
# If we're in a bulk operation context, skip hooks to prevent double execution
|
|
80
83
|
if current_bypass_hooks:
|
|
81
|
-
|
|
84
|
+
logger.debug("update skipping hooks (bulk context)")
|
|
82
85
|
ctx = HookContext(model_cls, bypass_hooks=True)
|
|
83
86
|
else:
|
|
84
|
-
|
|
87
|
+
logger.debug("update running hooks (standalone)")
|
|
85
88
|
ctx = HookContext(model_cls, bypass_hooks=False)
|
|
86
89
|
# Run validation hooks first
|
|
87
90
|
engine.run(model_cls, VALIDATE_UPDATE, instances, originals, ctx=ctx)
|
|
@@ -115,10 +118,10 @@ class HookQuerySetMixin:
|
|
|
115
118
|
|
|
116
119
|
# Run AFTER_UPDATE hooks only for standalone updates
|
|
117
120
|
if not current_bypass_hooks:
|
|
118
|
-
|
|
121
|
+
logger.debug("update running AFTER_UPDATE")
|
|
119
122
|
engine.run(model_cls, AFTER_UPDATE, instances, originals, ctx=ctx)
|
|
120
123
|
else:
|
|
121
|
-
|
|
124
|
+
logger.debug("update skipping AFTER_UPDATE (bulk context)")
|
|
122
125
|
|
|
123
126
|
return update_count
|
|
124
127
|
|
|
@@ -183,7 +186,7 @@ class HookQuerySetMixin:
|
|
|
183
186
|
engine.run(model_cls, BEFORE_CREATE, objs, ctx=ctx)
|
|
184
187
|
else:
|
|
185
188
|
ctx = HookContext(model_cls, bypass_hooks=True) # Pass bypass_hooks
|
|
186
|
-
|
|
189
|
+
logger.debug("bulk_create bypassed hooks")
|
|
187
190
|
|
|
188
191
|
# For MTI models, we need to handle them specially
|
|
189
192
|
if is_mti:
|
|
@@ -238,7 +241,7 @@ class HookQuerySetMixin:
|
|
|
238
241
|
f"bulk_update expected instances of {model_cls.__name__}, but got {set(type(obj).__name__ for obj in objs)}"
|
|
239
242
|
)
|
|
240
243
|
|
|
241
|
-
|
|
244
|
+
logger.debug(f"bulk_update {model_cls.__name__} bypass_hooks={bypass_hooks} objs={len(objs)}")
|
|
242
245
|
|
|
243
246
|
# Check for MTI
|
|
244
247
|
is_mti = False
|
|
@@ -248,11 +251,11 @@ class HookQuerySetMixin:
|
|
|
248
251
|
break
|
|
249
252
|
|
|
250
253
|
if not bypass_hooks:
|
|
251
|
-
|
|
254
|
+
logger.debug("bulk_update setting bypass_hooks=False (hooks will run in update())")
|
|
252
255
|
ctx = HookContext(model_cls, bypass_hooks=False)
|
|
253
256
|
originals = [None] * len(objs) # Placeholder for after_update call
|
|
254
257
|
else:
|
|
255
|
-
|
|
258
|
+
logger.debug("bulk_update setting bypass_hooks=True (no hooks)")
|
|
256
259
|
ctx = HookContext(model_cls, bypass_hooks=True)
|
|
257
260
|
originals = [None] * len(objs) # Ensure originals is defined for after_update call
|
|
258
261
|
|
|
@@ -279,16 +282,16 @@ class HookQuerySetMixin:
|
|
|
279
282
|
for k, v in kwargs.items()
|
|
280
283
|
if k not in ["bypass_hooks", "bypass_validation"]
|
|
281
284
|
}
|
|
282
|
-
|
|
285
|
+
logger.debug("Calling Django bulk_update")
|
|
283
286
|
result = super().bulk_update(objs, fields, **django_kwargs)
|
|
284
|
-
|
|
287
|
+
logger.debug(f"Django bulk_update done: {result}")
|
|
285
288
|
|
|
286
289
|
# Note: We don't run AFTER_UPDATE hooks here to prevent double execution
|
|
287
290
|
# The update() method will handle all hook execution based on thread-local state
|
|
288
291
|
if not bypass_hooks:
|
|
289
|
-
|
|
292
|
+
logger.debug("bulk_update skipping AFTER_UPDATE (update() will handle)")
|
|
290
293
|
else:
|
|
291
|
-
|
|
294
|
+
logger.debug("bulk_update bypassed hooks")
|
|
292
295
|
|
|
293
296
|
return result
|
|
294
297
|
|
|
@@ -14,13 +14,13 @@ def register_hook(
|
|
|
14
14
|
hooks.append((handler_cls, method_name, condition, priority))
|
|
15
15
|
# keep sorted by priority
|
|
16
16
|
hooks.sort(key=lambda x: x[3])
|
|
17
|
-
|
|
17
|
+
logger.debug(f"Registered {handler_cls.__name__}.{method_name} for {model.__name__}.{event}")
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
def get_hooks(model, event):
|
|
21
21
|
key = (model, event)
|
|
22
22
|
hooks = _hooks.get(key, [])
|
|
23
|
-
|
|
23
|
+
logger.debug(f"get_hooks {model.__name__}.{event} found {len(hooks)} hooks")
|
|
24
24
|
return hooks
|
|
25
25
|
|
|
26
26
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "django-bulk-hooks"
|
|
3
|
-
version = "0.1.
|
|
3
|
+
version = "0.1.219"
|
|
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
|