django-bulk-hooks 0.1.69__py3-none-any.whl → 0.1.71__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/conditions.py +0 -17
- django_bulk_hooks/engine.py +4 -39
- django_bulk_hooks/handler.py +0 -14
- django_bulk_hooks/manager.py +0 -14
- django_bulk_hooks/registry.py +0 -19
- {django_bulk_hooks-0.1.69.dist-info → django_bulk_hooks-0.1.71.dist-info}/METADATA +3 -3
- django_bulk_hooks-0.1.71.dist-info/RECORD +17 -0
- {django_bulk_hooks-0.1.69.dist-info → django_bulk_hooks-0.1.71.dist-info}/WHEEL +1 -1
- django_bulk_hooks-0.1.69.dist-info/RECORD +0 -17
- {django_bulk_hooks-0.1.69.dist-info → django_bulk_hooks-0.1.71.dist-info}/LICENSE +0 -0
django_bulk_hooks/conditions.py
CHANGED
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
import logging
|
|
2
|
-
|
|
3
|
-
logger = logging.getLogger(__name__)
|
|
4
|
-
|
|
5
|
-
|
|
6
1
|
def resolve_dotted_attr(instance, dotted_path):
|
|
7
2
|
"""
|
|
8
3
|
Recursively resolve a dotted attribute path, e.g., "type.category".
|
|
@@ -39,12 +34,6 @@ class IsNotEqual(HookCondition):
|
|
|
39
34
|
|
|
40
35
|
def check(self, instance, original_instance=None):
|
|
41
36
|
current = resolve_dotted_attr(instance, self.field)
|
|
42
|
-
logger.debug(
|
|
43
|
-
"%s current=%r, original=%r",
|
|
44
|
-
self.field,
|
|
45
|
-
current,
|
|
46
|
-
resolve_dotted_attr(original_instance, self.field) if original_instance else None,
|
|
47
|
-
)
|
|
48
37
|
if self.only_on_change:
|
|
49
38
|
if original_instance is None:
|
|
50
39
|
return False
|
|
@@ -62,12 +51,6 @@ class IsEqual(HookCondition):
|
|
|
62
51
|
|
|
63
52
|
def check(self, instance, original_instance=None):
|
|
64
53
|
current = resolve_dotted_attr(instance, self.field)
|
|
65
|
-
logger.debug(
|
|
66
|
-
"%s current=%r, original=%r",
|
|
67
|
-
self.field,
|
|
68
|
-
current,
|
|
69
|
-
resolve_dotted_attr(original_instance, self.field) if original_instance else None,
|
|
70
|
-
)
|
|
71
54
|
if self.only_on_change:
|
|
72
55
|
if original_instance is None:
|
|
73
56
|
return False
|
django_bulk_hooks/engine.py
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import logging
|
|
2
|
+
|
|
2
3
|
from django.core.exceptions import ValidationError
|
|
4
|
+
|
|
3
5
|
from django_bulk_hooks.registry import get_hooks
|
|
4
6
|
|
|
5
7
|
logger = logging.getLogger(__name__)
|
|
@@ -8,22 +10,11 @@ logger = logging.getLogger(__name__)
|
|
|
8
10
|
def run(model_cls, event, new_instances, original_instances=None, ctx=None):
|
|
9
11
|
hooks = get_hooks(model_cls, event)
|
|
10
12
|
|
|
11
|
-
logger.info(
|
|
12
|
-
"Executing engine.run: model=%s, event=%s, #new_instances=%d, #original_instances=%d, #hooks=%d",
|
|
13
|
-
model_cls.__name__,
|
|
14
|
-
event,
|
|
15
|
-
len(new_instances),
|
|
16
|
-
len(original_instances or []),
|
|
17
|
-
len(hooks),
|
|
18
|
-
)
|
|
19
|
-
|
|
20
13
|
if not hooks:
|
|
21
|
-
logger.info("No hooks found for model=%s, event=%s", model_cls.__name__, event)
|
|
22
14
|
return
|
|
23
15
|
|
|
24
16
|
# For BEFORE_* events, run model.clean() first for validation
|
|
25
17
|
if event.startswith("before_"):
|
|
26
|
-
logger.debug("Running model.clean() for %d instances", len(new_instances))
|
|
27
18
|
for instance in new_instances:
|
|
28
19
|
try:
|
|
29
20
|
instance.clean()
|
|
@@ -35,14 +26,6 @@ def run(model_cls, event, new_instances, original_instances=None, ctx=None):
|
|
|
35
26
|
handler_instance = handler_cls()
|
|
36
27
|
func = getattr(handler_instance, method_name)
|
|
37
28
|
|
|
38
|
-
logger.info(
|
|
39
|
-
"Executing hook %s for %s.%s with priority=%s",
|
|
40
|
-
func.__name__,
|
|
41
|
-
model_cls.__name__,
|
|
42
|
-
event,
|
|
43
|
-
priority,
|
|
44
|
-
)
|
|
45
|
-
|
|
46
29
|
to_process_new = []
|
|
47
30
|
to_process_old = []
|
|
48
31
|
|
|
@@ -51,28 +34,10 @@ def run(model_cls, event, new_instances, original_instances=None, ctx=None):
|
|
|
51
34
|
original_instances or [None] * len(new_instances),
|
|
52
35
|
strict=True,
|
|
53
36
|
):
|
|
54
|
-
logger.debug(
|
|
55
|
-
" considering instance: new=%r, original=%r",
|
|
56
|
-
new,
|
|
57
|
-
original,
|
|
58
|
-
)
|
|
59
|
-
|
|
60
37
|
if not condition or condition.check(new, original):
|
|
61
38
|
to_process_new.append(new)
|
|
62
39
|
to_process_old.append(original)
|
|
63
|
-
logger.debug(" -> will process (passed condition)")
|
|
64
|
-
else:
|
|
65
|
-
logger.debug(" -> skipped (condition returned False)")
|
|
66
40
|
|
|
67
41
|
if to_process_new:
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
func.__name__,
|
|
71
|
-
len(to_process_new),
|
|
72
|
-
to_process_new,
|
|
73
|
-
)
|
|
74
|
-
|
|
75
|
-
# Call the function with direct arguments
|
|
76
|
-
func(to_process_new, to_process_old if any(to_process_old) else None)
|
|
77
|
-
else:
|
|
78
|
-
logger.debug("No instances to process for hook %s", func.__name__)
|
|
42
|
+
# Call the function with keyword arguments
|
|
43
|
+
func(new_records=to_process_new, old_records=to_process_old if any(to_process_old) else None)
|
django_bulk_hooks/handler.py
CHANGED
|
@@ -74,13 +74,6 @@ class HookMeta(type):
|
|
|
74
74
|
for model_cls, event, condition, priority in method.hooks_hooks:
|
|
75
75
|
key = (model_cls, event, cls, method_name)
|
|
76
76
|
if key not in HookMeta._registered:
|
|
77
|
-
logger.info(
|
|
78
|
-
"Registering hook via HookMeta: model=%s, event=%s, handler_cls=%s, method_name=%s",
|
|
79
|
-
model_cls.__name__,
|
|
80
|
-
event,
|
|
81
|
-
cls.__name__,
|
|
82
|
-
method_name,
|
|
83
|
-
)
|
|
84
77
|
register_hook(
|
|
85
78
|
model=model_cls,
|
|
86
79
|
event=event,
|
|
@@ -131,7 +124,6 @@ class Hook(metaclass=HookMeta):
|
|
|
131
124
|
hook_vars.model = model
|
|
132
125
|
|
|
133
126
|
hooks = sorted(get_hooks(model, event), key=lambda x: x[3])
|
|
134
|
-
logger.debug("Processing %d hooks for %s.%s", len(hooks), model.__name__, event)
|
|
135
127
|
|
|
136
128
|
def _execute():
|
|
137
129
|
new_local = new_records or []
|
|
@@ -150,12 +142,6 @@ class Hook(metaclass=HookMeta):
|
|
|
150
142
|
handler = handler_cls()
|
|
151
143
|
method = getattr(handler, method_name)
|
|
152
144
|
|
|
153
|
-
logger.info(
|
|
154
|
-
"Running hook %s.%s on %d items",
|
|
155
|
-
handler_cls.__name__,
|
|
156
|
-
method_name,
|
|
157
|
-
len(new_local),
|
|
158
|
-
)
|
|
159
145
|
try:
|
|
160
146
|
method(
|
|
161
147
|
new_records=new_local,
|
django_bulk_hooks/manager.py
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
import logging
|
|
2
|
-
|
|
3
1
|
from django.db import models, transaction
|
|
4
|
-
|
|
5
2
|
from django_bulk_hooks import engine
|
|
6
3
|
from django_bulk_hooks.constants import (
|
|
7
4
|
AFTER_CREATE,
|
|
@@ -17,8 +14,6 @@ from django_bulk_hooks.constants import (
|
|
|
17
14
|
from django_bulk_hooks.context import HookContext
|
|
18
15
|
from django_bulk_hooks.queryset import HookQuerySet
|
|
19
16
|
|
|
20
|
-
logger = logging.getLogger(__name__)
|
|
21
|
-
|
|
22
17
|
|
|
23
18
|
class BulkHookManager(models.Manager):
|
|
24
19
|
CHUNK_SIZE = 200
|
|
@@ -56,10 +51,6 @@ class BulkHookManager(models.Manager):
|
|
|
56
51
|
fields_set = set(fields)
|
|
57
52
|
fields_set.update(modified_fields)
|
|
58
53
|
fields = list(fields_set)
|
|
59
|
-
logger.info(
|
|
60
|
-
"Automatically including modified fields in bulk_update: %s",
|
|
61
|
-
modified_fields,
|
|
62
|
-
)
|
|
63
54
|
|
|
64
55
|
for i in range(0, len(objs), self.CHUNK_SIZE):
|
|
65
56
|
chunk = objs[i : i + self.CHUNK_SIZE]
|
|
@@ -159,9 +150,6 @@ class BulkHookManager(models.Manager):
|
|
|
159
150
|
ctx = HookContext(model_cls)
|
|
160
151
|
|
|
161
152
|
if not bypass_hooks:
|
|
162
|
-
logger.info("Executing hooks for %s", model_cls.__name__)
|
|
163
|
-
logger.info("Number of objects to delete: %d", len(objs))
|
|
164
|
-
|
|
165
153
|
# Run validation hooks first
|
|
166
154
|
if not bypass_validation:
|
|
167
155
|
engine.run(model_cls, VALIDATE_DELETE, objs, ctx=ctx)
|
|
@@ -173,8 +161,6 @@ class BulkHookManager(models.Manager):
|
|
|
173
161
|
model_cls.objects.filter(pk__in=pks).delete()
|
|
174
162
|
|
|
175
163
|
if not bypass_hooks:
|
|
176
|
-
logger.info("Executing AFTER_DELETE hooks for %s", model_cls.__name__)
|
|
177
|
-
logger.info("Number of objects deleted: %d", len(objs))
|
|
178
164
|
engine.run(model_cls, AFTER_DELETE, objs, ctx=ctx)
|
|
179
165
|
|
|
180
166
|
return objs
|
django_bulk_hooks/registry.py
CHANGED
|
@@ -1,11 +1,8 @@
|
|
|
1
|
-
import logging
|
|
2
1
|
from collections.abc import Callable
|
|
3
2
|
from typing import Union
|
|
4
3
|
|
|
5
4
|
from django_bulk_hooks.priority import Priority
|
|
6
5
|
|
|
7
|
-
logger = logging.getLogger(__name__)
|
|
8
|
-
|
|
9
6
|
_hooks: dict[tuple[type, str], list[tuple[type, str, Callable, int]]] = {}
|
|
10
7
|
|
|
11
8
|
|
|
@@ -17,29 +14,13 @@ def register_hook(
|
|
|
17
14
|
hooks.append((handler_cls, method_name, condition, priority))
|
|
18
15
|
# keep sorted by priority
|
|
19
16
|
hooks.sort(key=lambda x: x[3])
|
|
20
|
-
logger.info(
|
|
21
|
-
"Registering hook: model=%s, event=%s, handler_cls=%s, method_name=%s, condition=%s, priority=%s",
|
|
22
|
-
model.__name__,
|
|
23
|
-
event,
|
|
24
|
-
handler_cls.__name__,
|
|
25
|
-
method_name,
|
|
26
|
-
condition,
|
|
27
|
-
priority,
|
|
28
|
-
)
|
|
29
17
|
|
|
30
18
|
|
|
31
19
|
def get_hooks(model, event):
|
|
32
20
|
hooks = _hooks.get((model, event), [])
|
|
33
|
-
logger.info(
|
|
34
|
-
"Retrieving hooks: model=%s, event=%s, hooks_found=%d",
|
|
35
|
-
model.__name__,
|
|
36
|
-
event,
|
|
37
|
-
len(hooks),
|
|
38
|
-
)
|
|
39
21
|
return hooks
|
|
40
22
|
|
|
41
23
|
|
|
42
24
|
def list_all_hooks():
|
|
43
25
|
"""Debug function to list all registered hooks"""
|
|
44
|
-
logger.debug("All registered hooks: %s", _hooks)
|
|
45
26
|
return _hooks
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
2
|
Name: django-bulk-hooks
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.71
|
|
4
4
|
Summary: Hook-style hooks for Django bulk operations like bulk_create and bulk_update.
|
|
5
|
-
Home-page: https://github.com/AugendLimited/django-bulk-hooks
|
|
6
5
|
License: MIT
|
|
7
6
|
Keywords: django,bulk,hooks
|
|
8
7
|
Author: Konrad Beck
|
|
@@ -14,6 +13,7 @@ Classifier: Programming Language :: Python :: 3.11
|
|
|
14
13
|
Classifier: Programming Language :: Python :: 3.12
|
|
15
14
|
Classifier: Programming Language :: Python :: 3.13
|
|
16
15
|
Requires-Dist: Django (>=4.0)
|
|
16
|
+
Project-URL: Homepage, https://github.com/AugendLimited/django-bulk-hooks
|
|
17
17
|
Project-URL: Repository, https://github.com/AugendLimited/django-bulk-hooks
|
|
18
18
|
Description-Content-Type: text/markdown
|
|
19
19
|
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
django_bulk_hooks/__init__.py,sha256=uUgpnb9AWjIAcWNpCMqBcOewSnpJjJYH6cjPbQkzoNU,140
|
|
2
|
+
django_bulk_hooks/conditions.py,sha256=mTvlLcttixbXRkTSNZU5VewkPUavbXRuD2BkJbVWMkw,6041
|
|
3
|
+
django_bulk_hooks/constants.py,sha256=3x1H1fSUUNo0DZONN7GUVDuySZctTR-jtByBHmAIX5w,303
|
|
4
|
+
django_bulk_hooks/context.py,sha256=HVDT73uSzvgrOR6mdXTvsBm3hLOgBU8ant_mB7VlFuM,380
|
|
5
|
+
django_bulk_hooks/decorators.py,sha256=tckDcxtOzKCbgvS9QydgeIAWTFDEl-ch3_Q--ruEGdQ,4831
|
|
6
|
+
django_bulk_hooks/engine.py,sha256=3HbgV12JRYIy9IlygHPxZiHnFXj7EwzLyTuJNQeVIoI,1402
|
|
7
|
+
django_bulk_hooks/enums.py,sha256=Zo8_tJzuzZ2IKfVc7gZ-0tWPT8q1QhqZbAyoh9ZVJbs,381
|
|
8
|
+
django_bulk_hooks/handler.py,sha256=xZt8iNdYF-ACz-MnKMY0co6scWINU5V5wC1lyDn844k,4854
|
|
9
|
+
django_bulk_hooks/manager.py,sha256=8ifRsHFJZXViTHdKbVWFd35MF5xHvGqu9UttgsLrkVU,6911
|
|
10
|
+
django_bulk_hooks/models.py,sha256=7RG7GrOdHXFjGVPV4FPRZVNMIHHW-hMCi6hn9LH_hVI,3331
|
|
11
|
+
django_bulk_hooks/priority.py,sha256=HG_2D35nga68lBCZmSXTcplXrjFoRgZFRDOy4ROKonY,376
|
|
12
|
+
django_bulk_hooks/queryset.py,sha256=nmVZ6cqkveSiBz_L4cRT-3u-mkcjkGQNJLhza8SSdKc,1398
|
|
13
|
+
django_bulk_hooks/registry.py,sha256=-mQBizJ06nz_tajZBinViKx_uP2Tbc1tIpTEMv7lwKA,705
|
|
14
|
+
django_bulk_hooks-0.1.71.dist-info/LICENSE,sha256=dguKIcbDGeZD-vXWdLyErPUALYOvtX_fO4Zjhq481uk,1088
|
|
15
|
+
django_bulk_hooks-0.1.71.dist-info/METADATA,sha256=Ys-lGAZiQXE46EtkP8t_0DxNbqwtJPhisRDa2LWe-HA,5930
|
|
16
|
+
django_bulk_hooks-0.1.71.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
|
17
|
+
django_bulk_hooks-0.1.71.dist-info/RECORD,,
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
django_bulk_hooks/__init__.py,sha256=uUgpnb9AWjIAcWNpCMqBcOewSnpJjJYH6cjPbQkzoNU,140
|
|
2
|
-
django_bulk_hooks/conditions.py,sha256=S8o8JLAeYoF5hNUaxmC2QwMtmak0C73aI-j4GtgmbAw,6541
|
|
3
|
-
django_bulk_hooks/constants.py,sha256=3x1H1fSUUNo0DZONN7GUVDuySZctTR-jtByBHmAIX5w,303
|
|
4
|
-
django_bulk_hooks/context.py,sha256=HVDT73uSzvgrOR6mdXTvsBm3hLOgBU8ant_mB7VlFuM,380
|
|
5
|
-
django_bulk_hooks/decorators.py,sha256=tckDcxtOzKCbgvS9QydgeIAWTFDEl-ch3_Q--ruEGdQ,4831
|
|
6
|
-
django_bulk_hooks/engine.py,sha256=My339hWu8L2iZ6GQeEJ3M6LGTraKbp8vG6cO8_Vpi2Y,2632
|
|
7
|
-
django_bulk_hooks/enums.py,sha256=Zo8_tJzuzZ2IKfVc7gZ-0tWPT8q1QhqZbAyoh9ZVJbs,381
|
|
8
|
-
django_bulk_hooks/handler.py,sha256=w0t6cCR9y4ooGEXoxTVlJHBqdAIS0MeSh5E6kvU5Cok,5511
|
|
9
|
-
django_bulk_hooks/manager.py,sha256=90wOzdtkM2xaXXh7pGzV0E5kPkJlfkIZJILdEFjUxUc,7450
|
|
10
|
-
django_bulk_hooks/models.py,sha256=7RG7GrOdHXFjGVPV4FPRZVNMIHHW-hMCi6hn9LH_hVI,3331
|
|
11
|
-
django_bulk_hooks/priority.py,sha256=HG_2D35nga68lBCZmSXTcplXrjFoRgZFRDOy4ROKonY,376
|
|
12
|
-
django_bulk_hooks/queryset.py,sha256=nmVZ6cqkveSiBz_L4cRT-3u-mkcjkGQNJLhza8SSdKc,1398
|
|
13
|
-
django_bulk_hooks/registry.py,sha256=2S_MUrhFJpGPZbBuqFvPEpKgEduGYUAsxqMS3_wsVXA,1233
|
|
14
|
-
django_bulk_hooks-0.1.69.dist-info/LICENSE,sha256=dguKIcbDGeZD-vXWdLyErPUALYOvtX_fO4Zjhq481uk,1088
|
|
15
|
-
django_bulk_hooks-0.1.69.dist-info/METADATA,sha256=kiyQOr6EB4UyBTeomqcjOTdTvuS6Vn1gWB1qhjlo58A,5918
|
|
16
|
-
django_bulk_hooks-0.1.69.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
|
|
17
|
-
django_bulk_hooks-0.1.69.dist-info/RECORD,,
|
|
File without changes
|