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.

@@ -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
- qs = HookQuerySet(self.model, using=self._db)
9
- return qs
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
- import inspect
60
-
61
- qs = self.get_queryset()
62
-
63
- # Check if this is our HookQuerySet or a different QuerySet
64
- if (
65
- hasattr(qs, "bulk_create")
66
- and "bypass_hooks" in inspect.signature(qs.bulk_create).parameters
67
- ):
68
- # Our HookQuerySet - pass all parameters
69
- kwargs = {
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 bulk_delete(
94
- self, objs, batch_size=None, bypass_hooks=False, bypass_validation=False
39
+ def bulk_update(
40
+ self, objs, fields, bypass_hooks=False, bypass_validation=False, **kwargs
95
41
  ):
96
42
  """
97
- Delegate to QuerySet's bulk_delete implementation.
43
+ Delegate to QuerySet's bulk_update implementation.
98
44
  This follows Django's pattern where Manager methods call QuerySet methods.
99
45
  """
100
- import inspect
101
-
102
- qs = self.get_queryset()
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
- # Check if this is our HookQuerySet or a different QuerySet
105
- if (
106
- hasattr(qs, "bulk_delete")
107
- and "bypass_hooks" in inspect.signature(qs.bulk_delete).parameters
108
- ):
109
- # Our HookQuerySet - pass all parameters
110
- kwargs = {
111
- "batch_size": batch_size,
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 update implementation.
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().update(**kwargs)
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.
@@ -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
- # Use Django's original QuerySet to avoid recursive calls
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
- for i in range(0, len(objs), self.CHUNK_SIZE):
230
- chunk = objs[i : i + self.CHUNK_SIZE]
231
-
232
- # Call the base implementation to avoid re-triggering this method
233
- # Filter out custom parameters that Django's bulk_update doesn't accept
234
- django_kwargs = {
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
1
+ Metadata-Version: 2.3
2
2
  Name: django-bulk-hooks
3
- Version: 0.1.175
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=OSzW8eVzknLV1WCvZcBkWMz9x_Vjq4bJM8raVXKiZvI,5085
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=wP1PHzDJ-n_F6RtPzQUdB2j16aALabDl0gbaMJAE2eI,22812
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.175.dist-info/LICENSE,sha256=dguKIcbDGeZD-vXWdLyErPUALYOvtX_fO4Zjhq481uk,1088
15
- django_bulk_hooks-0.1.175.dist-info/METADATA,sha256=HmgU2xtMNjhwLejwg5ehchMkJPSYn6B_JRcRmn3EoXs,6939
16
- django_bulk_hooks-0.1.175.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
17
- django_bulk_hooks-0.1.175.dist-info/RECORD,,
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,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 1.9.1
2
+ Generator: poetry-core 2.1.3
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any