django-bulk-hooks 0.1.235__py3-none-any.whl → 0.1.236__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/context.py +16 -0
- django_bulk_hooks/queryset.py +33 -3
- {django_bulk_hooks-0.1.235.dist-info → django_bulk_hooks-0.1.236.dist-info}/METADATA +1 -1
- {django_bulk_hooks-0.1.235.dist-info → django_bulk_hooks-0.1.236.dist-info}/RECORD +6 -6
- {django_bulk_hooks-0.1.235.dist-info → django_bulk_hooks-0.1.236.dist-info}/LICENSE +0 -0
- {django_bulk_hooks-0.1.235.dist-info → django_bulk_hooks-0.1.236.dist-info}/WHEEL +0 -0
django_bulk_hooks/context.py
CHANGED
|
@@ -22,6 +22,22 @@ def get_bypass_hooks():
|
|
|
22
22
|
return getattr(_hook_context, 'bypass_hooks', False)
|
|
23
23
|
|
|
24
24
|
|
|
25
|
+
# Thread-local storage for passing per-object field values from bulk_update -> update
|
|
26
|
+
def set_bulk_update_value_map(value_map):
|
|
27
|
+
"""Store a mapping of {pk: {field_name: value}} for the current thread.
|
|
28
|
+
|
|
29
|
+
This allows the internal update() call (triggered by Django's bulk_update)
|
|
30
|
+
to populate in-memory instances with the concrete values that will be
|
|
31
|
+
written to the database, instead of Django expression objects like Case/Cast.
|
|
32
|
+
"""
|
|
33
|
+
_hook_context.bulk_update_value_map = value_map
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def get_bulk_update_value_map():
|
|
37
|
+
"""Retrieve the mapping {pk: {field_name: value}} for the current thread, if any."""
|
|
38
|
+
return getattr(_hook_context, 'bulk_update_value_map', None)
|
|
39
|
+
|
|
40
|
+
|
|
25
41
|
class HookContext:
|
|
26
42
|
def __init__(self, model, bypass_hooks=False):
|
|
27
43
|
self.model = model
|
django_bulk_hooks/queryset.py
CHANGED
|
@@ -17,6 +17,10 @@ from django_bulk_hooks.constants import (
|
|
|
17
17
|
VALIDATE_UPDATE,
|
|
18
18
|
)
|
|
19
19
|
from django_bulk_hooks.context import HookContext
|
|
20
|
+
from django_bulk_hooks.context import (
|
|
21
|
+
get_bulk_update_value_map,
|
|
22
|
+
set_bulk_update_value_map,
|
|
23
|
+
)
|
|
20
24
|
|
|
21
25
|
|
|
22
26
|
class HookQuerySetMixin:
|
|
@@ -71,9 +75,15 @@ class HookQuerySetMixin:
|
|
|
71
75
|
)
|
|
72
76
|
|
|
73
77
|
# Apply field updates to instances
|
|
78
|
+
# If a per-object value map exists (from bulk_update), prefer it over kwargs
|
|
79
|
+
per_object_values = get_bulk_update_value_map()
|
|
74
80
|
for obj in instances:
|
|
75
|
-
|
|
76
|
-
|
|
81
|
+
if per_object_values and obj.pk in per_object_values:
|
|
82
|
+
for field, value in per_object_values[obj.pk].items():
|
|
83
|
+
setattr(obj, field, value)
|
|
84
|
+
else:
|
|
85
|
+
for field, value in kwargs.items():
|
|
86
|
+
setattr(obj, field, value)
|
|
77
87
|
|
|
78
88
|
# Check if we're in a bulk operation context to prevent double hook execution
|
|
79
89
|
from django_bulk_hooks.context import get_bypass_hooks
|
|
@@ -283,7 +293,27 @@ class HookQuerySetMixin:
|
|
|
283
293
|
if k not in ["bypass_hooks", "bypass_validation"]
|
|
284
294
|
}
|
|
285
295
|
logger.debug("Calling Django bulk_update")
|
|
286
|
-
|
|
296
|
+
# Build a per-object concrete value map to avoid leaking expressions into hooks
|
|
297
|
+
value_map = {}
|
|
298
|
+
for obj in objs:
|
|
299
|
+
if obj.pk is None:
|
|
300
|
+
continue
|
|
301
|
+
field_values = {}
|
|
302
|
+
for field_name in fields:
|
|
303
|
+
# Capture raw values assigned on the object (not expressions)
|
|
304
|
+
field_values[field_name] = getattr(obj, field_name)
|
|
305
|
+
if field_values:
|
|
306
|
+
value_map[obj.pk] = field_values
|
|
307
|
+
|
|
308
|
+
# Make the value map available to the subsequent update() call
|
|
309
|
+
if value_map:
|
|
310
|
+
set_bulk_update_value_map(value_map)
|
|
311
|
+
|
|
312
|
+
try:
|
|
313
|
+
result = super().bulk_update(objs, fields, **django_kwargs)
|
|
314
|
+
finally:
|
|
315
|
+
# Always clear after the internal update() path finishes
|
|
316
|
+
set_bulk_update_value_map(None)
|
|
287
317
|
logger.debug(f"Django bulk_update done: {result}")
|
|
288
318
|
|
|
289
319
|
# Note: We don't run AFTER_UPDATE hooks here to prevent double execution
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
django_bulk_hooks/__init__.py,sha256=uUgpnb9AWjIAcWNpCMqBcOewSnpJjJYH6cjPbQkzoNU,140
|
|
2
2
|
django_bulk_hooks/conditions.py,sha256=V_f3Di2uCVUjoyfiU4BQCHmI4uUIRSRroApDcXlvnso,6349
|
|
3
3
|
django_bulk_hooks/constants.py,sha256=3x1H1fSUUNo0DZONN7GUVDuySZctTR-jtByBHmAIX5w,303
|
|
4
|
-
django_bulk_hooks/context.py,sha256=
|
|
4
|
+
django_bulk_hooks/context.py,sha256=jlLsqGZbj__J0-iBUp1D6jTrlDEiX3qIo0XlywW4D9I,2244
|
|
5
5
|
django_bulk_hooks/decorators.py,sha256=WD7Jn7QAvY8F4wOsYlIpjoM9-FdHXSKB7hH9ot-lkYQ,4896
|
|
6
6
|
django_bulk_hooks/engine.py,sha256=t_kvgex6_iZEFc5LK-srBTZPe-1bdlYdip5LfWOc6lc,2411
|
|
7
7
|
django_bulk_hooks/enums.py,sha256=Zo8_tJzuzZ2IKfVc7gZ-0tWPT8q1QhqZbAyoh9ZVJbs,381
|
|
@@ -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=
|
|
12
|
+
django_bulk_hooks/queryset.py,sha256=wRT3g7shlHkpa0p0m5TjuyrS8SQKNmdhpcjdaSSMQHM,33937
|
|
13
13
|
django_bulk_hooks/registry.py,sha256=8UuhniiH5ChSeOKV1UUbqTEiIu25bZXvcHmkaRbxmME,1131
|
|
14
|
-
django_bulk_hooks-0.1.
|
|
15
|
-
django_bulk_hooks-0.1.
|
|
16
|
-
django_bulk_hooks-0.1.
|
|
17
|
-
django_bulk_hooks-0.1.
|
|
14
|
+
django_bulk_hooks-0.1.236.dist-info/LICENSE,sha256=dguKIcbDGeZD-vXWdLyErPUALYOvtX_fO4Zjhq481uk,1088
|
|
15
|
+
django_bulk_hooks-0.1.236.dist-info/METADATA,sha256=030mLHnwBTnsBWPmxLBc0KX9Qwrd2Yx0G3VDvZkVTps,9049
|
|
16
|
+
django_bulk_hooks-0.1.236.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
|
|
17
|
+
django_bulk_hooks-0.1.236.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|