django-bulk-hooks 0.1.175__py3-none-any.whl → 0.1.177__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/manager.py +47 -99
- django_bulk_hooks/queryset.py +20 -29
- {django_bulk_hooks-0.1.175.dist-info → django_bulk_hooks-0.1.177.dist-info}/METADATA +3 -3
- {django_bulk_hooks-0.1.175.dist-info → django_bulk_hooks-0.1.177.dist-info}/RECORD +6 -6
- {django_bulk_hooks-0.1.175.dist-info → django_bulk_hooks-0.1.177.dist-info}/WHEEL +1 -1
- {django_bulk_hooks-0.1.175.dist-info → django_bulk_hooks-0.1.177.dist-info}/LICENSE +0 -0
django_bulk_hooks/manager.py
CHANGED
|
@@ -5,41 +5,8 @@ from django_bulk_hooks.queryset import HookQuerySet
|
|
|
5
5
|
|
|
6
6
|
class BulkHookManager(models.Manager):
|
|
7
7
|
def get_queryset(self):
|
|
8
|
-
|
|
9
|
-
return
|
|
10
|
-
|
|
11
|
-
def bulk_update(
|
|
12
|
-
self, objs, fields, bypass_hooks=False, bypass_validation=False, **kwargs
|
|
13
|
-
):
|
|
14
|
-
"""
|
|
15
|
-
Delegate to QuerySet's bulk_update implementation.
|
|
16
|
-
This follows Django's pattern where Manager methods call QuerySet methods.
|
|
17
|
-
"""
|
|
18
|
-
import inspect
|
|
19
|
-
|
|
20
|
-
qs = self.get_queryset()
|
|
21
|
-
|
|
22
|
-
# Check if this is our HookQuerySet or a different QuerySet
|
|
23
|
-
if (
|
|
24
|
-
hasattr(qs, "bulk_update")
|
|
25
|
-
and "bypass_hooks" in inspect.signature(qs.bulk_update).parameters
|
|
26
|
-
):
|
|
27
|
-
# Our HookQuerySet - pass all parameters
|
|
28
|
-
return qs.bulk_update(
|
|
29
|
-
objs,
|
|
30
|
-
fields,
|
|
31
|
-
bypass_hooks=bypass_hooks,
|
|
32
|
-
bypass_validation=bypass_validation,
|
|
33
|
-
**kwargs,
|
|
34
|
-
)
|
|
35
|
-
else:
|
|
36
|
-
# Different QuerySet (like queryable_properties) - only pass standard parameters
|
|
37
|
-
django_kwargs = {
|
|
38
|
-
k: v
|
|
39
|
-
for k, v in kwargs.items()
|
|
40
|
-
if k not in ["bypass_hooks", "bypass_validation"]
|
|
41
|
-
}
|
|
42
|
-
return qs.bulk_update(objs, fields, **django_kwargs)
|
|
8
|
+
queryset = HookQuerySet(self.model, using=self._db)
|
|
9
|
+
return queryset
|
|
43
10
|
|
|
44
11
|
def bulk_create(
|
|
45
12
|
self,
|
|
@@ -51,84 +18,58 @@ class BulkHookManager(models.Manager):
|
|
|
51
18
|
unique_fields=None,
|
|
52
19
|
bypass_hooks=False,
|
|
53
20
|
bypass_validation=False,
|
|
21
|
+
**kwargs,
|
|
54
22
|
):
|
|
55
23
|
"""
|
|
56
24
|
Delegate to QuerySet's bulk_create implementation.
|
|
57
25
|
This follows Django's pattern where Manager methods call QuerySet methods.
|
|
58
26
|
"""
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
"batch_size": batch_size,
|
|
71
|
-
"ignore_conflicts": ignore_conflicts,
|
|
72
|
-
"update_conflicts": update_conflicts,
|
|
73
|
-
"update_fields": update_fields,
|
|
74
|
-
"unique_fields": unique_fields,
|
|
75
|
-
}
|
|
76
|
-
return qs.bulk_create(
|
|
77
|
-
objs,
|
|
78
|
-
bypass_hooks=bypass_hooks,
|
|
79
|
-
bypass_validation=bypass_validation,
|
|
80
|
-
**kwargs,
|
|
81
|
-
)
|
|
82
|
-
else:
|
|
83
|
-
# Different QuerySet - only pass standard parameters
|
|
84
|
-
kwargs = {
|
|
85
|
-
"batch_size": batch_size,
|
|
86
|
-
"ignore_conflicts": ignore_conflicts,
|
|
87
|
-
"update_conflicts": update_conflicts,
|
|
88
|
-
"update_fields": update_fields,
|
|
89
|
-
"unique_fields": unique_fields,
|
|
90
|
-
}
|
|
91
|
-
return qs.bulk_create(objs, **kwargs)
|
|
27
|
+
return self.get_queryset().bulk_create(
|
|
28
|
+
objs,
|
|
29
|
+
bypass_hooks=bypass_hooks,
|
|
30
|
+
bypass_validation=bypass_validation,
|
|
31
|
+
batch_size=batch_size,
|
|
32
|
+
ignore_conflicts=ignore_conflicts,
|
|
33
|
+
update_conflicts=update_conflicts,
|
|
34
|
+
update_fields=update_fields,
|
|
35
|
+
unique_fields=unique_fields,
|
|
36
|
+
**kwargs,
|
|
37
|
+
)
|
|
92
38
|
|
|
93
|
-
def
|
|
94
|
-
self, objs,
|
|
39
|
+
def bulk_update(
|
|
40
|
+
self, objs, fields, bypass_hooks=False, bypass_validation=False, **kwargs
|
|
95
41
|
):
|
|
96
42
|
"""
|
|
97
|
-
Delegate to QuerySet's
|
|
43
|
+
Delegate to QuerySet's bulk_update implementation.
|
|
98
44
|
This follows Django's pattern where Manager methods call QuerySet methods.
|
|
99
45
|
"""
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
46
|
+
return self.get_queryset().bulk_update(
|
|
47
|
+
objs,
|
|
48
|
+
fields,
|
|
49
|
+
bypass_hooks=bypass_hooks,
|
|
50
|
+
bypass_validation=bypass_validation,
|
|
51
|
+
**kwargs,
|
|
52
|
+
)
|
|
103
53
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
}
|
|
113
|
-
return qs.bulk_delete(
|
|
114
|
-
objs,
|
|
115
|
-
bypass_hooks=bypass_hooks,
|
|
116
|
-
bypass_validation=bypass_validation,
|
|
117
|
-
**kwargs,
|
|
118
|
-
)
|
|
119
|
-
else:
|
|
120
|
-
# Different QuerySet - only pass standard parameters
|
|
121
|
-
kwargs = {
|
|
122
|
-
"batch_size": batch_size,
|
|
123
|
-
}
|
|
124
|
-
return qs.bulk_delete(objs, **kwargs)
|
|
125
|
-
|
|
126
|
-
def update(self, **kwargs):
|
|
54
|
+
def bulk_delete(
|
|
55
|
+
self,
|
|
56
|
+
objs,
|
|
57
|
+
batch_size=None,
|
|
58
|
+
bypass_hooks=False,
|
|
59
|
+
bypass_validation=False,
|
|
60
|
+
**kwargs,
|
|
61
|
+
):
|
|
127
62
|
"""
|
|
128
|
-
Delegate to QuerySet's
|
|
63
|
+
Delegate to QuerySet's bulk_delete implementation.
|
|
129
64
|
This follows Django's pattern where Manager methods call QuerySet methods.
|
|
130
65
|
"""
|
|
131
|
-
return self.get_queryset().
|
|
66
|
+
return self.get_queryset().bulk_delete(
|
|
67
|
+
objs,
|
|
68
|
+
bypass_hooks=bypass_hooks,
|
|
69
|
+
bypass_validation=bypass_validation,
|
|
70
|
+
batch_size=batch_size,
|
|
71
|
+
**kwargs,
|
|
72
|
+
)
|
|
132
73
|
|
|
133
74
|
def delete(self):
|
|
134
75
|
"""
|
|
@@ -137,6 +78,13 @@ class BulkHookManager(models.Manager):
|
|
|
137
78
|
"""
|
|
138
79
|
return self.get_queryset().delete()
|
|
139
80
|
|
|
81
|
+
def update(self, **kwargs):
|
|
82
|
+
"""
|
|
83
|
+
Delegate to QuerySet's update implementation.
|
|
84
|
+
This follows Django's pattern where Manager methods call QuerySet methods.
|
|
85
|
+
"""
|
|
86
|
+
return self.get_queryset().update(**kwargs)
|
|
87
|
+
|
|
140
88
|
def save(self, obj):
|
|
141
89
|
"""
|
|
142
90
|
Save a single object using the appropriate bulk operation.
|
django_bulk_hooks/queryset.py
CHANGED
|
@@ -109,6 +109,14 @@ class HookQuerySet(models.QuerySet):
|
|
|
109
109
|
# trickier so it's not done yet.
|
|
110
110
|
if batch_size is not None and batch_size <= 0:
|
|
111
111
|
raise ValueError("Batch size must be a positive integer.")
|
|
112
|
+
|
|
113
|
+
if not objs:
|
|
114
|
+
return objs
|
|
115
|
+
|
|
116
|
+
if any(not isinstance(obj, model_cls) for obj in objs):
|
|
117
|
+
raise TypeError(
|
|
118
|
+
f"bulk_create expected instances of {model_cls.__name__}, but got {set(type(obj).__name__ for obj in objs)}"
|
|
119
|
+
)
|
|
112
120
|
|
|
113
121
|
# Check for MTI - if we detect multi-table inheritance, we need special handling
|
|
114
122
|
# This follows Django's approach: check that the parents share the same concrete model
|
|
@@ -121,14 +129,6 @@ class HookQuerySet(models.QuerySet):
|
|
|
121
129
|
is_mti = True
|
|
122
130
|
break
|
|
123
131
|
|
|
124
|
-
if not objs:
|
|
125
|
-
return objs
|
|
126
|
-
|
|
127
|
-
if any(not isinstance(obj, model_cls) for obj in objs):
|
|
128
|
-
raise TypeError(
|
|
129
|
-
f"bulk_create expected instances of {model_cls.__name__}, but got {set(type(obj).__name__ for obj in objs)}"
|
|
130
|
-
)
|
|
131
|
-
|
|
132
132
|
# Fire hooks before DB ops
|
|
133
133
|
if not bypass_hooks:
|
|
134
134
|
ctx = HookContext(model_cls)
|
|
@@ -150,22 +150,14 @@ class HookQuerySet(models.QuerySet):
|
|
|
150
150
|
# Remove custom hook kwargs if present in self.bulk_create signature
|
|
151
151
|
result = self._mti_bulk_create(
|
|
152
152
|
objs,
|
|
153
|
-
|
|
154
|
-
k: v
|
|
155
|
-
for k, v in mti_kwargs.items()
|
|
156
|
-
if k not in ["bypass_hooks", "bypass_validation"]
|
|
157
|
-
},
|
|
153
|
+
mti_kwargs,
|
|
158
154
|
)
|
|
159
155
|
else:
|
|
160
156
|
# For single-table models, use Django's built-in bulk_create
|
|
161
157
|
# but we need to call it on the base manager to avoid recursion
|
|
162
158
|
# Filter out custom parameters that Django's bulk_create doesn't accept
|
|
163
159
|
|
|
164
|
-
|
|
165
|
-
from django.db.models import QuerySet
|
|
166
|
-
|
|
167
|
-
original_qs = QuerySet(model_cls, using=self.db)
|
|
168
|
-
result = original_qs.bulk_create(
|
|
160
|
+
result = super().bulk_create(
|
|
169
161
|
objs,
|
|
170
162
|
batch_size=batch_size,
|
|
171
163
|
ignore_conflicts=ignore_conflicts,
|
|
@@ -226,17 +218,12 @@ class HookQuerySet(models.QuerySet):
|
|
|
226
218
|
fields_set.update(modified_fields)
|
|
227
219
|
fields = list(fields_set)
|
|
228
220
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
k: v
|
|
236
|
-
for k, v in kwargs.items()
|
|
237
|
-
if k not in ["bypass_hooks", "bypass_validation"]
|
|
238
|
-
}
|
|
239
|
-
super().bulk_update(chunk, fields, **django_kwargs)
|
|
221
|
+
django_kwargs = {
|
|
222
|
+
k: v
|
|
223
|
+
for k, v in kwargs.items()
|
|
224
|
+
if k not in ["bypass_hooks", "bypass_validation"]
|
|
225
|
+
}
|
|
226
|
+
super().bulk_update(objs, fields, **django_kwargs)
|
|
240
227
|
|
|
241
228
|
if not bypass_hooks:
|
|
242
229
|
engine.run(model_cls, AFTER_UPDATE, objs, originals, ctx=ctx)
|
|
@@ -315,6 +302,10 @@ class HookQuerySet(models.QuerySet):
|
|
|
315
302
|
if inheritance_chain is None:
|
|
316
303
|
inheritance_chain = self._get_inheritance_chain()
|
|
317
304
|
|
|
305
|
+
for inheritance in inheritance_chain:
|
|
306
|
+
print(inheritance)
|
|
307
|
+
|
|
308
|
+
|
|
318
309
|
# Safety check to prevent infinite recursion
|
|
319
310
|
if len(inheritance_chain) > 10: # Arbitrary limit to prevent infinite loops
|
|
320
311
|
raise ValueError(
|
|
@@ -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.177
|
|
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
|
|
|
@@ -6,12 +6,12 @@ django_bulk_hooks/decorators.py,sha256=WD7Jn7QAvY8F4wOsYlIpjoM9-FdHXSKB7hH9ot-lk
|
|
|
6
6
|
django_bulk_hooks/engine.py,sha256=nA5PU9msk_Ju5Gf_sTd7GqPscuTxEW5itCDAoSScYGI,1645
|
|
7
7
|
django_bulk_hooks/enums.py,sha256=Zo8_tJzuzZ2IKfVc7gZ-0tWPT8q1QhqZbAyoh9ZVJbs,381
|
|
8
8
|
django_bulk_hooks/handler.py,sha256=xZt8iNdYF-ACz-MnKMY0co6scWINU5V5wC1lyDn844k,4854
|
|
9
|
-
django_bulk_hooks/manager.py,sha256=
|
|
9
|
+
django_bulk_hooks/manager.py,sha256=KLEjpQRt4WlzgBAf_X3XOAPUQM8Jmc1fIt8yr62FPQc,3044
|
|
10
10
|
django_bulk_hooks/models.py,sha256=7fnx5xd4HWXfLVlFhhiRzR92JRWFEuxgk6aSWLEsyJg,3996
|
|
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=unW-YBkiS5NbuPwOdbRK05ZOKRi7KjSxevyKX22NxmU,22270
|
|
13
13
|
django_bulk_hooks/registry.py,sha256=-mQBizJ06nz_tajZBinViKx_uP2Tbc1tIpTEMv7lwKA,705
|
|
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.177.dist-info/LICENSE,sha256=dguKIcbDGeZD-vXWdLyErPUALYOvtX_fO4Zjhq481uk,1088
|
|
15
|
+
django_bulk_hooks-0.1.177.dist-info/METADATA,sha256=99nhQDIQt5uMqZedTPGw7wB1VLpkE0VacnVeyk2koiM,6951
|
|
16
|
+
django_bulk_hooks-0.1.177.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
|
17
|
+
django_bulk_hooks-0.1.177.dist-info/RECORD,,
|
|
File without changes
|