django-bulk-hooks 0.1.120__tar.gz → 0.1.122__tar.gz

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.

Files changed (17) hide show
  1. {django_bulk_hooks-0.1.120 → django_bulk_hooks-0.1.122}/PKG-INFO +1 -1
  2. {django_bulk_hooks-0.1.120 → django_bulk_hooks-0.1.122}/django_bulk_hooks/queryset.py +23 -8
  3. {django_bulk_hooks-0.1.120 → django_bulk_hooks-0.1.122}/pyproject.toml +1 -1
  4. {django_bulk_hooks-0.1.120 → django_bulk_hooks-0.1.122}/LICENSE +0 -0
  5. {django_bulk_hooks-0.1.120 → django_bulk_hooks-0.1.122}/README.md +0 -0
  6. {django_bulk_hooks-0.1.120 → django_bulk_hooks-0.1.122}/django_bulk_hooks/__init__.py +0 -0
  7. {django_bulk_hooks-0.1.120 → django_bulk_hooks-0.1.122}/django_bulk_hooks/conditions.py +0 -0
  8. {django_bulk_hooks-0.1.120 → django_bulk_hooks-0.1.122}/django_bulk_hooks/constants.py +0 -0
  9. {django_bulk_hooks-0.1.120 → django_bulk_hooks-0.1.122}/django_bulk_hooks/context.py +0 -0
  10. {django_bulk_hooks-0.1.120 → django_bulk_hooks-0.1.122}/django_bulk_hooks/decorators.py +0 -0
  11. {django_bulk_hooks-0.1.120 → django_bulk_hooks-0.1.122}/django_bulk_hooks/engine.py +0 -0
  12. {django_bulk_hooks-0.1.120 → django_bulk_hooks-0.1.122}/django_bulk_hooks/enums.py +0 -0
  13. {django_bulk_hooks-0.1.120 → django_bulk_hooks-0.1.122}/django_bulk_hooks/handler.py +0 -0
  14. {django_bulk_hooks-0.1.120 → django_bulk_hooks-0.1.122}/django_bulk_hooks/manager.py +0 -0
  15. {django_bulk_hooks-0.1.120 → django_bulk_hooks-0.1.122}/django_bulk_hooks/models.py +0 -0
  16. {django_bulk_hooks-0.1.120 → django_bulk_hooks-0.1.122}/django_bulk_hooks/priority.py +0 -0
  17. {django_bulk_hooks-0.1.120 → django_bulk_hooks-0.1.122}/django_bulk_hooks/registry.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: django-bulk-hooks
3
- Version: 0.1.120
3
+ Version: 0.1.122
4
4
  Summary: Hook-style hooks for Django bulk operations like bulk_create and bulk_update.
5
5
  License: MIT
6
6
  Keywords: django,bulk,hooks
@@ -284,6 +284,10 @@ class HookQuerySet(models.QuerySet):
284
284
  if inheritance_chain is None:
285
285
  inheritance_chain = self._get_inheritance_chain()
286
286
 
287
+ # Safety check to prevent infinite recursion
288
+ if len(inheritance_chain) > 10: # Arbitrary limit to prevent infinite loops
289
+ raise ValueError("Inheritance chain too deep - possible infinite recursion detected")
290
+
287
291
  batch_size = kwargs.get("batch_size") or len(objs)
288
292
  created_objects = []
289
293
  with transaction.atomic(using=self.db, savepoint=False):
@@ -323,19 +327,28 @@ class HookQuerySet(models.QuerySet):
323
327
  # If the child model is still MTI, call our own logic recursively
324
328
  if len([p for p in child_model._meta.parents.keys() if not p._meta.proxy]) > 0:
325
329
  # Build inheritance chain for the child model
326
- inheritance_chain = []
330
+ child_inheritance_chain = []
327
331
  current_model = child_model
328
332
  while current_model:
329
333
  if not current_model._meta.proxy:
330
- inheritance_chain.append(current_model)
334
+ child_inheritance_chain.append(current_model)
331
335
  parents = [
332
336
  parent
333
337
  for parent in current_model._meta.parents.keys()
334
338
  if not parent._meta.proxy
335
339
  ]
336
340
  current_model = parents[0] if parents else None
337
- inheritance_chain.reverse()
338
- created = self._mti_bulk_create(child_objects, inheritance_chain, **kwargs)
341
+ child_inheritance_chain.reverse()
342
+
343
+ # For nested MTI, we can't use bulk operations recursively
344
+ # because it would create infinite recursion. Instead, we save each child individually.
345
+ # We use super().save() to avoid triggering hooks that would cause recursion.
346
+ created = []
347
+ for child_obj in child_objects:
348
+ # Use the base model's save method to avoid triggering hooks
349
+ # This prevents infinite recursion when hooks try to query the database
350
+ super(child_obj.__class__, child_obj).save()
351
+ created.append(child_obj)
339
352
  else:
340
353
  # Single-table, safe to use bulk_create
341
354
 
@@ -370,8 +383,9 @@ class HookQuerySet(models.QuerySet):
370
383
 
371
384
  # Handle auto_now_add and auto_now fields like Django does
372
385
  for field in parent_model._meta.local_fields:
373
- if field.__class__.pre_save is not field.__class__.__bases__[0].pre_save:
374
- # This field has a custom pre_save method (like auto_now_add/auto_now)
386
+ if hasattr(field, 'auto_now_add') and field.auto_now_add:
387
+ field.pre_save(parent_obj, add=True)
388
+ elif hasattr(field, 'auto_now') and field.auto_now:
375
389
  field.pre_save(parent_obj, add=True)
376
390
 
377
391
  return parent_obj
@@ -392,8 +406,9 @@ class HookQuerySet(models.QuerySet):
392
406
 
393
407
  # Handle auto_now_add and auto_now fields like Django does
394
408
  for field in child_model._meta.local_fields:
395
- if field.__class__.pre_save is not field.__class__.__bases__[0].pre_save:
396
- # This field has a custom pre_save method (like auto_now_add/auto_now)
409
+ if hasattr(field, 'auto_now_add') and field.auto_now_add:
410
+ field.pre_save(child_obj, add=True)
411
+ elif hasattr(field, 'auto_now') and field.auto_now:
397
412
  field.pre_save(child_obj, add=True)
398
413
 
399
414
  return child_obj
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "django-bulk-hooks"
3
- version = "0.1.120"
3
+ version = "0.1.122"
4
4
  description = "Hook-style hooks for Django bulk operations like bulk_create and bulk_update."
5
5
  authors = ["Konrad Beck <konrad.beck@merchantcapital.co.za>"]
6
6
  readme = "README.md"