django-bulk-hooks 0.2.5__py3-none-any.whl → 0.2.6__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.
- django_bulk_hooks/operations/coordinator.py +90 -3
- {django_bulk_hooks-0.2.5.dist-info → django_bulk_hooks-0.2.6.dist-info}/METADATA +1 -1
- {django_bulk_hooks-0.2.5.dist-info → django_bulk_hooks-0.2.6.dist-info}/RECORD +5 -5
- {django_bulk_hooks-0.2.5.dist-info → django_bulk_hooks-0.2.6.dist-info}/LICENSE +0 -0
- {django_bulk_hooks-0.2.5.dist-info → django_bulk_hooks-0.2.6.dist-info}/WHEEL +0 -0
|
@@ -143,7 +143,7 @@ class BulkOperationCoordinator:
|
|
|
143
143
|
unique_fields=unique_fields,
|
|
144
144
|
)
|
|
145
145
|
|
|
146
|
-
return self.
|
|
146
|
+
return self._execute_with_mti_hooks(
|
|
147
147
|
changeset=changeset,
|
|
148
148
|
operation=operation,
|
|
149
149
|
event_prefix="create",
|
|
@@ -199,7 +199,7 @@ class BulkOperationCoordinator:
|
|
|
199
199
|
def operation():
|
|
200
200
|
return self.executor.bulk_update(objs, fields, batch_size=batch_size)
|
|
201
201
|
|
|
202
|
-
return self.
|
|
202
|
+
return self._execute_with_mti_hooks(
|
|
203
203
|
changeset=changeset,
|
|
204
204
|
operation=operation,
|
|
205
205
|
event_prefix="update",
|
|
@@ -343,7 +343,7 @@ class BulkOperationCoordinator:
|
|
|
343
343
|
# Call base Django QuerySet.delete() to avoid recursion
|
|
344
344
|
return BaseQuerySet.delete(self.queryset)
|
|
345
345
|
|
|
346
|
-
return self.
|
|
346
|
+
return self._execute_with_mti_hooks(
|
|
347
347
|
changeset=changeset,
|
|
348
348
|
operation=operation,
|
|
349
349
|
event_prefix="delete",
|
|
@@ -383,3 +383,90 @@ class BulkOperationCoordinator:
|
|
|
383
383
|
|
|
384
384
|
# Dispatch validation event only
|
|
385
385
|
self.dispatcher.dispatch(changeset, event, bypass_hooks=False)
|
|
386
|
+
|
|
387
|
+
# ==================== MTI PARENT HOOK SUPPORT ====================
|
|
388
|
+
|
|
389
|
+
def _build_changeset_for_model(self, original_changeset, target_model_cls):
|
|
390
|
+
"""
|
|
391
|
+
Build a changeset for a specific model in the MTI inheritance chain.
|
|
392
|
+
|
|
393
|
+
This allows parent model hooks to receive the same instances but with
|
|
394
|
+
the correct model_cls for hook registration matching.
|
|
395
|
+
|
|
396
|
+
Args:
|
|
397
|
+
original_changeset: The original changeset (for child model)
|
|
398
|
+
target_model_cls: The model class to build changeset for (parent model)
|
|
399
|
+
|
|
400
|
+
Returns:
|
|
401
|
+
ChangeSet for the target model
|
|
402
|
+
"""
|
|
403
|
+
from django_bulk_hooks.changeset import ChangeSet
|
|
404
|
+
|
|
405
|
+
# Create new changeset with target model but same record changes
|
|
406
|
+
return ChangeSet(
|
|
407
|
+
model_cls=target_model_cls,
|
|
408
|
+
changes=original_changeset.changes,
|
|
409
|
+
operation_type=original_changeset.operation_type,
|
|
410
|
+
operation_meta=original_changeset.operation_meta,
|
|
411
|
+
)
|
|
412
|
+
|
|
413
|
+
def _execute_with_mti_hooks(
|
|
414
|
+
self,
|
|
415
|
+
changeset,
|
|
416
|
+
operation,
|
|
417
|
+
event_prefix,
|
|
418
|
+
bypass_hooks=False,
|
|
419
|
+
bypass_validation=False
|
|
420
|
+
):
|
|
421
|
+
"""
|
|
422
|
+
Execute operation with hooks for entire MTI inheritance chain.
|
|
423
|
+
|
|
424
|
+
This method dispatches hooks for both child and parent models when
|
|
425
|
+
dealing with MTI models, ensuring parent model hooks fire when
|
|
426
|
+
child instances are created/updated/deleted.
|
|
427
|
+
|
|
428
|
+
Args:
|
|
429
|
+
changeset: ChangeSet for the child model
|
|
430
|
+
operation: Callable that performs the actual DB operation
|
|
431
|
+
event_prefix: 'create', 'update', or 'delete'
|
|
432
|
+
bypass_hooks: Skip all hooks if True
|
|
433
|
+
bypass_validation: Skip validation hooks if True
|
|
434
|
+
|
|
435
|
+
Returns:
|
|
436
|
+
Result of operation
|
|
437
|
+
"""
|
|
438
|
+
if bypass_hooks:
|
|
439
|
+
return operation()
|
|
440
|
+
|
|
441
|
+
# Get all models in inheritance chain
|
|
442
|
+
models_in_chain = [changeset.model_cls]
|
|
443
|
+
if self.mti_handler.is_mti_model():
|
|
444
|
+
parent_models = self.mti_handler.get_parent_models()
|
|
445
|
+
models_in_chain.extend(parent_models)
|
|
446
|
+
|
|
447
|
+
# VALIDATE phase - for all models in chain
|
|
448
|
+
if not bypass_validation:
|
|
449
|
+
for model_cls in models_in_chain:
|
|
450
|
+
model_changeset = self._build_changeset_for_model(changeset, model_cls)
|
|
451
|
+
self.dispatcher.dispatch(model_changeset, f"validate_{event_prefix}", bypass_hooks=False)
|
|
452
|
+
|
|
453
|
+
# BEFORE phase - for all models in chain
|
|
454
|
+
for model_cls in models_in_chain:
|
|
455
|
+
model_changeset = self._build_changeset_for_model(changeset, model_cls)
|
|
456
|
+
self.dispatcher.dispatch(model_changeset, f"before_{event_prefix}", bypass_hooks=False)
|
|
457
|
+
|
|
458
|
+
# Execute the actual operation
|
|
459
|
+
result = operation()
|
|
460
|
+
|
|
461
|
+
# AFTER phase - for all models in chain
|
|
462
|
+
# Use result if operation returns modified data (for create operations)
|
|
463
|
+
if result and isinstance(result, list) and event_prefix == "create":
|
|
464
|
+
# Rebuild changeset with assigned PKs for AFTER hooks
|
|
465
|
+
from django_bulk_hooks.helpers import build_changeset_for_create
|
|
466
|
+
changeset = build_changeset_for_create(changeset.model_cls, result)
|
|
467
|
+
|
|
468
|
+
for model_cls in models_in_chain:
|
|
469
|
+
model_changeset = self._build_changeset_for_model(changeset, model_cls)
|
|
470
|
+
self.dispatcher.dispatch(model_changeset, f"after_{event_prefix}", bypass_hooks=False)
|
|
471
|
+
|
|
472
|
+
return result
|
|
@@ -15,12 +15,12 @@ django_bulk_hooks/models.py,sha256=62tn5wL55EjJVOsZofMluhEJB8bH7CzBvH0vd214_RY,2
|
|
|
15
15
|
django_bulk_hooks/operations/__init__.py,sha256=5L5NnwiFw8Yn5WO6-38eGdCYBkA0URpwyDcAdeYfc5w,550
|
|
16
16
|
django_bulk_hooks/operations/analyzer.py,sha256=s6FM53ho1raPdKU-VjjW0SWymXyrJe0I_Wu8XsXFdSY,9065
|
|
17
17
|
django_bulk_hooks/operations/bulk_executor.py,sha256=PuRVS5OlOysZ3qEHMsadr06rZt5CoZL6tgzqBAvDQxY,17825
|
|
18
|
-
django_bulk_hooks/operations/coordinator.py,sha256=
|
|
18
|
+
django_bulk_hooks/operations/coordinator.py,sha256=XH84Vl8pLVOWXzpUuTNf6bX6Zm0__no02TFfr6DW6Jg,16599
|
|
19
19
|
django_bulk_hooks/operations/mti_handler.py,sha256=eIH-tImMqcWR5lLQr6Ca-HeVYta-UkXk5X5fcpS885Y,18245
|
|
20
20
|
django_bulk_hooks/operations/mti_plans.py,sha256=fHUYbrUAHq8UXqxgAD43oHdTxOnEkmpxoOD4Qrzfqk8,2878
|
|
21
21
|
django_bulk_hooks/queryset.py,sha256=ody4MXrRREL27Ts2ey1UpS0tb5Dxnw-6kN3unxPQ3zY,5860
|
|
22
22
|
django_bulk_hooks/registry.py,sha256=UPerNhtVz_9tKZqrYSZD2LhjAcs4F6hVUuk8L5oOeHc,8821
|
|
23
|
-
django_bulk_hooks-0.2.
|
|
24
|
-
django_bulk_hooks-0.2.
|
|
25
|
-
django_bulk_hooks-0.2.
|
|
26
|
-
django_bulk_hooks-0.2.
|
|
23
|
+
django_bulk_hooks-0.2.6.dist-info/LICENSE,sha256=dguKIcbDGeZD-vXWdLyErPUALYOvtX_fO4Zjhq481uk,1088
|
|
24
|
+
django_bulk_hooks-0.2.6.dist-info/METADATA,sha256=kqgreJGTaZUXBl-aGNfNHndcixC866-PhBO2b7nfglc,9264
|
|
25
|
+
django_bulk_hooks-0.2.6.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
|
26
|
+
django_bulk_hooks-0.2.6.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|