django-bulk-hooks 0.1.63__tar.gz → 0.1.65__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.63 → django_bulk_hooks-0.1.65}/PKG-INFO +1 -1
  2. {django_bulk_hooks-0.1.63 → django_bulk_hooks-0.1.65}/django_bulk_hooks/decorators.py +0 -1
  3. {django_bulk_hooks-0.1.63 → django_bulk_hooks-0.1.65}/django_bulk_hooks/engine.py +1 -1
  4. {django_bulk_hooks-0.1.63 → django_bulk_hooks-0.1.65}/django_bulk_hooks/manager.py +14 -14
  5. {django_bulk_hooks-0.1.63 → django_bulk_hooks-0.1.65}/django_bulk_hooks/registry.py +19 -0
  6. {django_bulk_hooks-0.1.63 → django_bulk_hooks-0.1.65}/pyproject.toml +1 -1
  7. {django_bulk_hooks-0.1.63 → django_bulk_hooks-0.1.65}/LICENSE +0 -0
  8. {django_bulk_hooks-0.1.63 → django_bulk_hooks-0.1.65}/README.md +0 -0
  9. {django_bulk_hooks-0.1.63 → django_bulk_hooks-0.1.65}/django_bulk_hooks/__init__.py +0 -0
  10. {django_bulk_hooks-0.1.63 → django_bulk_hooks-0.1.65}/django_bulk_hooks/conditions.py +0 -0
  11. {django_bulk_hooks-0.1.63 → django_bulk_hooks-0.1.65}/django_bulk_hooks/constants.py +0 -0
  12. {django_bulk_hooks-0.1.63 → django_bulk_hooks-0.1.65}/django_bulk_hooks/context.py +0 -0
  13. {django_bulk_hooks-0.1.63 → django_bulk_hooks-0.1.65}/django_bulk_hooks/enums.py +0 -0
  14. {django_bulk_hooks-0.1.63 → django_bulk_hooks-0.1.65}/django_bulk_hooks/handler.py +0 -0
  15. {django_bulk_hooks-0.1.63 → django_bulk_hooks-0.1.65}/django_bulk_hooks/models.py +0 -0
  16. {django_bulk_hooks-0.1.63 → django_bulk_hooks-0.1.65}/django_bulk_hooks/priority.py +0 -0
  17. {django_bulk_hooks-0.1.63 → django_bulk_hooks-0.1.65}/django_bulk_hooks/queryset.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: django-bulk-hooks
3
- Version: 0.1.63
3
+ Version: 0.1.65
4
4
  Summary: Lifecycle-style hooks for Django bulk operations like bulk_create and bulk_update.
5
5
  License: MIT
6
6
  Keywords: django,bulk,hooks
@@ -3,7 +3,6 @@ from functools import wraps
3
3
 
4
4
  from django.core.exceptions import FieldDoesNotExist
5
5
  from django_bulk_hooks.enums import DEFAULT_PRIORITY
6
- from django_bulk_hooks.constants import BEFORE_UPDATE
7
6
  from django_bulk_hooks.registry import register_hook
8
7
 
9
8
 
@@ -9,7 +9,7 @@ def run(model_cls, event, new_instances, original_instances=None, ctx=None):
9
9
  hooks = get_hooks(model_cls, event)
10
10
 
11
11
  logger.debug(
12
- "bulk_hooks.run: model=%s, event=%s, #new=%d, #original=%d",
12
+ "Executing engine.run: model=%s, event=%s, #new_instances=%d, #original_instances=%d",
13
13
  model_cls.__name__,
14
14
  event,
15
15
  len(new_instances),
@@ -37,7 +37,7 @@ class BulkLifecycleManager(models.Manager):
37
37
  originals = list(model_cls.objects.filter(pk__in=[obj.pk for obj in objs]))
38
38
  ctx = TriggerContext(model_cls)
39
39
  engine.run(model_cls, BEFORE_UPDATE, objs, originals, ctx=ctx)
40
-
40
+
41
41
  # Automatically detect fields that were modified during BEFORE_UPDATE hooks
42
42
  modified_fields = self._detect_modified_fields(objs, originals)
43
43
  if modified_fields:
@@ -47,7 +47,7 @@ class BulkLifecycleManager(models.Manager):
47
47
  fields = list(fields_set)
48
48
  logger.info(
49
49
  "Automatically including modified fields in bulk_update: %s",
50
- modified_fields
50
+ modified_fields,
51
51
  )
52
52
 
53
53
  for i in range(0, len(objs), self.CHUNK_SIZE):
@@ -67,28 +67,28 @@ class BulkLifecycleManager(models.Manager):
67
67
  """
68
68
  if not original_instances:
69
69
  return set()
70
-
70
+
71
71
  # Create a mapping of pk to original instance for efficient lookup
72
72
  original_map = {obj.pk: obj for obj in original_instances if obj.pk is not None}
73
-
73
+
74
74
  modified_fields = set()
75
-
75
+
76
76
  for new_instance in new_instances:
77
77
  if new_instance.pk is None:
78
78
  continue
79
-
79
+
80
80
  original = original_map.get(new_instance.pk)
81
81
  if not original:
82
82
  continue
83
-
83
+
84
84
  # Compare all fields to detect changes
85
85
  for field in new_instance._meta.fields:
86
- if field.name == 'id':
86
+ if field.name == "id":
87
87
  continue
88
-
88
+
89
89
  new_value = getattr(new_instance, field.name)
90
90
  original_value = getattr(original, field.name)
91
-
91
+
92
92
  # Handle different field types appropriately
93
93
  if field.is_relation:
94
94
  # For foreign keys, compare the pk values
@@ -100,7 +100,7 @@ class BulkLifecycleManager(models.Manager):
100
100
  # For regular fields, use direct comparison
101
101
  if new_value != original_value:
102
102
  modified_fields.add(field.name)
103
-
103
+
104
104
  return modified_fields
105
105
 
106
106
  @transaction.atomic
@@ -120,9 +120,7 @@ class BulkLifecycleManager(models.Manager):
120
120
 
121
121
  for i in range(0, len(objs), self.CHUNK_SIZE):
122
122
  chunk = objs[i : i + self.CHUNK_SIZE]
123
- result.extend(
124
- super(models.Manager, self).bulk_create(chunk, **kwargs)
125
- )
123
+ result.extend(super(models.Manager, self).bulk_create(chunk, **kwargs))
126
124
 
127
125
  if not bypass_hooks:
128
126
  engine.run(model_cls, AFTER_CREATE, result, ctx=ctx)
@@ -144,12 +142,14 @@ class BulkLifecycleManager(models.Manager):
144
142
  ctx = TriggerContext(model_cls)
145
143
 
146
144
  if not bypass_hooks:
145
+ logger.debug("Executing BEFORE_DELETE hooks for %s", model_cls.__name__)
147
146
  engine.run(model_cls, BEFORE_DELETE, objs, ctx=ctx)
148
147
 
149
148
  pks = [obj.pk for obj in objs if obj.pk is not None]
150
149
  model_cls.objects.filter(pk__in=pks).delete()
151
150
 
152
151
  if not bypass_hooks:
152
+ logger.debug("Executing AFTER_DELETE hooks for %s", model_cls.__name__)
153
153
  engine.run(model_cls, AFTER_DELETE, objs, ctx=ctx)
154
154
 
155
155
  return objs
@@ -3,6 +3,10 @@ from typing import Union
3
3
 
4
4
  from django_bulk_hooks.priority import Priority
5
5
 
6
+ import logging
7
+
8
+ logger = logging.getLogger(__name__)
9
+
6
10
  _hooks: dict[tuple[type, str], list[tuple[type, str, Callable, int]]] = {}
7
11
 
8
12
 
@@ -14,7 +18,22 @@ def register_hook(
14
18
  hooks.append((handler_cls, method_name, condition, priority))
15
19
  # keep sorted by priority
16
20
  hooks.sort(key=lambda x: x[3])
21
+ logger.debug(
22
+ "Registering hook: model=%s, event=%s, handler_cls=%s, method_name=%s, condition=%s, priority=%s",
23
+ model.__name__,
24
+ event,
25
+ handler_cls.__name__,
26
+ method_name,
27
+ condition,
28
+ priority,
29
+ )
17
30
 
18
31
 
19
32
  def get_hooks(model, event):
33
+ logger.debug(
34
+ "Retrieving hooks: model=%s, event=%s, hooks_found=%d",
35
+ model.__name__,
36
+ event,
37
+ len(_hooks.get((model, event), [])),
38
+ )
20
39
  return _hooks.get((model, event), [])
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "django-bulk-hooks"
3
- version = "0.1.63"
3
+ version = "0.1.65"
4
4
  description = "Lifecycle-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"