django-bulk-hooks 0.1.231__py3-none-any.whl → 0.1.233__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/__init__.py +1 -12
- django_bulk_hooks/conditions.py +30 -33
- django_bulk_hooks/context.py +15 -43
- django_bulk_hooks/decorators.py +8 -111
- django_bulk_hooks/engine.py +41 -127
- django_bulk_hooks/enums.py +13 -10
- django_bulk_hooks/handler.py +73 -40
- django_bulk_hooks/manager.py +101 -123
- django_bulk_hooks/models.py +15 -51
- django_bulk_hooks/priority.py +6 -6
- django_bulk_hooks/queryset.py +181 -306
- django_bulk_hooks/registry.py +24 -191
- {django_bulk_hooks-0.1.231.dist-info → django_bulk_hooks-0.1.233.dist-info}/METADATA +16 -32
- django_bulk_hooks-0.1.233.dist-info/RECORD +17 -0
- {django_bulk_hooks-0.1.231.dist-info → django_bulk_hooks-0.1.233.dist-info}/WHEEL +1 -1
- django_bulk_hooks-0.1.231.dist-info/RECORD +0 -17
- {django_bulk_hooks-0.1.231.dist-info → django_bulk_hooks-0.1.233.dist-info}/LICENSE +0 -0
django_bulk_hooks/models.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import logging
|
|
2
|
-
from django.db import models
|
|
2
|
+
from django.db import models
|
|
3
|
+
|
|
3
4
|
from django_bulk_hooks.constants import (
|
|
4
5
|
AFTER_CREATE,
|
|
5
6
|
AFTER_DELETE,
|
|
@@ -41,49 +42,32 @@ class HookModelMixin(models.Model):
|
|
|
41
42
|
|
|
42
43
|
if is_create:
|
|
43
44
|
# For create operations, run VALIDATE_CREATE hooks for validation
|
|
44
|
-
ctx = HookContext(self.__class__
|
|
45
|
+
ctx = HookContext(self.__class__)
|
|
45
46
|
run(self.__class__, VALIDATE_CREATE, [self], ctx=ctx)
|
|
46
47
|
else:
|
|
47
48
|
# For update operations, run VALIDATE_UPDATE hooks for validation
|
|
48
49
|
try:
|
|
49
50
|
# Use _base_manager to avoid triggering hooks recursively
|
|
50
51
|
old_instance = self.__class__._base_manager.get(pk=self.pk)
|
|
51
|
-
ctx = HookContext(self.__class__
|
|
52
|
+
ctx = HookContext(self.__class__)
|
|
52
53
|
run(self.__class__, VALIDATE_UPDATE, [self], [old_instance], ctx=ctx)
|
|
53
54
|
except self.__class__.DoesNotExist:
|
|
54
55
|
# If the old instance doesn't exist, treat as create
|
|
55
|
-
ctx = HookContext(self.__class__
|
|
56
|
+
ctx = HookContext(self.__class__)
|
|
56
57
|
run(self.__class__, VALIDATE_CREATE, [self], ctx=ctx)
|
|
57
58
|
|
|
58
59
|
def save(self, *args, bypass_hooks=False, **kwargs):
|
|
59
|
-
# If bypass_hooks is True,
|
|
60
|
+
# If bypass_hooks is True, use base manager to avoid triggering hooks
|
|
60
61
|
if bypass_hooks:
|
|
61
62
|
logger.debug(f"save() called with bypass_hooks=True for {self.__class__.__name__} pk={self.pk}")
|
|
62
|
-
|
|
63
|
-
return super().save(*args, **kwargs)
|
|
64
|
-
|
|
65
|
-
# Only create a new transaction if we're not already in one
|
|
66
|
-
# This allows for proper nested transaction handling
|
|
67
|
-
from django.db import connection
|
|
68
|
-
if connection.in_atomic_block:
|
|
69
|
-
# We're already in a transaction, don't create a new one
|
|
70
|
-
return self._save_with_hooks(*args, **kwargs)
|
|
71
|
-
else:
|
|
72
|
-
# We're not in a transaction, so create one
|
|
73
|
-
with transaction.atomic():
|
|
74
|
-
return self._save_with_hooks(*args, **kwargs)
|
|
63
|
+
return self._base_manager.save(self, *args, **kwargs)
|
|
75
64
|
|
|
76
|
-
def _save_with_hooks(self, *args, **kwargs):
|
|
77
|
-
"""Internal method to handle save with hooks."""
|
|
78
65
|
is_create = self.pk is None
|
|
79
|
-
|
|
66
|
+
|
|
80
67
|
if is_create:
|
|
81
68
|
logger.debug(f"save() creating new {self.__class__.__name__} instance")
|
|
82
69
|
# For create operations, we don't have old records
|
|
83
|
-
ctx = HookContext(self.__class__
|
|
84
|
-
|
|
85
|
-
# Run hooks - if any fail, the transaction will be rolled back
|
|
86
|
-
run(self.__class__, VALIDATE_CREATE, [self], ctx=ctx)
|
|
70
|
+
ctx = HookContext(self.__class__)
|
|
87
71
|
run(self.__class__, BEFORE_CREATE, [self], ctx=ctx)
|
|
88
72
|
|
|
89
73
|
super().save(*args, **kwargs)
|
|
@@ -95,10 +79,7 @@ class HookModelMixin(models.Model):
|
|
|
95
79
|
try:
|
|
96
80
|
# Use _base_manager to avoid triggering hooks recursively
|
|
97
81
|
old_instance = self.__class__._base_manager.get(pk=self.pk)
|
|
98
|
-
ctx = HookContext(self.__class__
|
|
99
|
-
|
|
100
|
-
# Run hooks - if any fail, the transaction will be rolled back
|
|
101
|
-
run(self.__class__, VALIDATE_UPDATE, [self], [old_instance], ctx=ctx)
|
|
82
|
+
ctx = HookContext(self.__class__)
|
|
102
83
|
run(self.__class__, BEFORE_UPDATE, [self], [old_instance], ctx=ctx)
|
|
103
84
|
|
|
104
85
|
super().save(*args, **kwargs)
|
|
@@ -106,10 +87,7 @@ class HookModelMixin(models.Model):
|
|
|
106
87
|
run(self.__class__, AFTER_UPDATE, [self], [old_instance], ctx=ctx)
|
|
107
88
|
except self.__class__.DoesNotExist:
|
|
108
89
|
# If the old instance doesn't exist, treat as create
|
|
109
|
-
ctx = HookContext(self.__class__
|
|
110
|
-
|
|
111
|
-
# Run hooks - if any fail, the transaction will be rolled back
|
|
112
|
-
run(self.__class__, VALIDATE_CREATE, [self], ctx=ctx)
|
|
90
|
+
ctx = HookContext(self.__class__)
|
|
113
91
|
run(self.__class__, BEFORE_CREATE, [self], ctx=ctx)
|
|
114
92
|
|
|
115
93
|
super().save(*args, **kwargs)
|
|
@@ -119,27 +97,13 @@ class HookModelMixin(models.Model):
|
|
|
119
97
|
return self
|
|
120
98
|
|
|
121
99
|
def delete(self, *args, bypass_hooks=False, **kwargs):
|
|
122
|
-
# If bypass_hooks is True,
|
|
100
|
+
# If bypass_hooks is True, use base manager to avoid triggering hooks
|
|
123
101
|
if bypass_hooks:
|
|
124
|
-
|
|
125
|
-
return super().delete(*args, **kwargs)
|
|
126
|
-
|
|
127
|
-
# Only create a new transaction if we're not already in one
|
|
128
|
-
# This allows for proper nested transaction handling
|
|
129
|
-
from django.db import connection
|
|
130
|
-
if connection.in_atomic_block:
|
|
131
|
-
# We're already in a transaction, don't create a new one
|
|
132
|
-
return self._delete_with_hooks(*args, **kwargs)
|
|
133
|
-
else:
|
|
134
|
-
# We're not in a transaction, so create one
|
|
135
|
-
with transaction.atomic():
|
|
136
|
-
return self._delete_with_hooks(*args, **kwargs)
|
|
102
|
+
return self._base_manager.delete(self, *args, **kwargs)
|
|
137
103
|
|
|
138
|
-
|
|
139
|
-
"""Internal method to handle delete with hooks."""
|
|
140
|
-
ctx = HookContext(self.__class__, bypass_hooks=False)
|
|
104
|
+
ctx = HookContext(self.__class__)
|
|
141
105
|
|
|
142
|
-
# Run hooks
|
|
106
|
+
# Run validation hooks first
|
|
143
107
|
run(self.__class__, VALIDATE_DELETE, [self], ctx=ctx)
|
|
144
108
|
|
|
145
109
|
# Then run business logic hooks
|
django_bulk_hooks/priority.py
CHANGED
|
@@ -5,12 +5,12 @@ class Priority(IntEnum):
|
|
|
5
5
|
"""
|
|
6
6
|
Named priorities for django-bulk-hooks hooks.
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
Hooks are sorted in
|
|
8
|
+
Lower values run earlier (higher priority).
|
|
9
|
+
Hooks are sorted in ascending order.
|
|
10
10
|
"""
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
HIGHEST = 0 # runs first
|
|
13
|
+
HIGH = 25 # runs early
|
|
14
14
|
NORMAL = 50 # default ordering
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
LOW = 75 # runs later
|
|
16
|
+
LOWEST = 100 # runs last
|