django-bulk-hooks 0.2.7__py3-none-any.whl → 0.2.8__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/conditions.py +24 -24
- {django_bulk_hooks-0.2.7.dist-info → django_bulk_hooks-0.2.8.dist-info}/METADATA +1 -1
- {django_bulk_hooks-0.2.7.dist-info → django_bulk_hooks-0.2.8.dist-info}/RECORD +5 -5
- {django_bulk_hooks-0.2.7.dist-info → django_bulk_hooks-0.2.8.dist-info}/LICENSE +0 -0
- {django_bulk_hooks-0.2.7.dist-info → django_bulk_hooks-0.2.8.dist-info}/WHEEL +0 -0
django_bulk_hooks/conditions.py
CHANGED
|
@@ -3,38 +3,38 @@ import logging
|
|
|
3
3
|
logger = logging.getLogger(__name__)
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
def
|
|
6
|
+
def resolve_field_path(instance, field_path):
|
|
7
7
|
"""
|
|
8
|
-
Recursively resolve a
|
|
8
|
+
Recursively resolve a field path using Django's __ notation, e.g., "author__profile__name".
|
|
9
9
|
|
|
10
10
|
CRITICAL: For foreign key fields, uses attname to access the ID directly
|
|
11
11
|
to avoid hooking Django's descriptor protocol which causes N+1 queries.
|
|
12
12
|
"""
|
|
13
|
-
# For simple field access (no
|
|
14
|
-
if "
|
|
13
|
+
# For simple field access (no __), use optimized field access
|
|
14
|
+
if "__" not in field_path:
|
|
15
15
|
try:
|
|
16
16
|
# Get the field from the model's meta to check if it's a foreign key
|
|
17
|
-
field = instance._meta.get_field(
|
|
17
|
+
field = instance._meta.get_field(field_path)
|
|
18
18
|
if field.is_relation and not field.many_to_many:
|
|
19
19
|
# For foreign key fields, use attname to get the ID directly
|
|
20
20
|
# This avoids hooking Django's descriptor protocol
|
|
21
21
|
return getattr(instance, field.attname, None)
|
|
22
22
|
else:
|
|
23
23
|
# For regular fields, use normal getattr
|
|
24
|
-
return getattr(instance,
|
|
24
|
+
return getattr(instance, field_path, None)
|
|
25
25
|
except Exception:
|
|
26
26
|
# If field lookup fails, fall back to normal getattr
|
|
27
|
-
return getattr(instance,
|
|
27
|
+
return getattr(instance, field_path, None)
|
|
28
28
|
|
|
29
|
-
# For
|
|
29
|
+
# For paths with __, traverse the relationship chain with FK optimization
|
|
30
30
|
current_instance = instance
|
|
31
|
-
for i, attr in enumerate(
|
|
31
|
+
for i, attr in enumerate(field_path.split("__")):
|
|
32
32
|
if current_instance is None:
|
|
33
33
|
return None
|
|
34
34
|
|
|
35
35
|
try:
|
|
36
36
|
# Check if this is the last attribute and if it's a FK field
|
|
37
|
-
is_last_attr = i == len(
|
|
37
|
+
is_last_attr = i == len(field_path.split("__")) - 1
|
|
38
38
|
if is_last_attr and hasattr(current_instance, "_meta"):
|
|
39
39
|
try:
|
|
40
40
|
field = current_instance._meta.get_field(attr)
|
|
@@ -79,11 +79,11 @@ class IsNotEqual(HookCondition):
|
|
|
79
79
|
self.only_on_change = only_on_change
|
|
80
80
|
|
|
81
81
|
def check(self, instance, original_instance=None):
|
|
82
|
-
current =
|
|
82
|
+
current = resolve_field_path(instance, self.field)
|
|
83
83
|
if self.only_on_change:
|
|
84
84
|
if original_instance is None:
|
|
85
85
|
return False
|
|
86
|
-
previous =
|
|
86
|
+
previous = resolve_field_path(original_instance, self.field)
|
|
87
87
|
return previous == self.value and current != self.value
|
|
88
88
|
else:
|
|
89
89
|
return current != self.value
|
|
@@ -96,12 +96,12 @@ class IsEqual(HookCondition):
|
|
|
96
96
|
self.only_on_change = only_on_change
|
|
97
97
|
|
|
98
98
|
def check(self, instance, original_instance=None):
|
|
99
|
-
current =
|
|
99
|
+
current = resolve_field_path(instance, self.field)
|
|
100
100
|
|
|
101
101
|
if self.only_on_change:
|
|
102
102
|
if original_instance is None:
|
|
103
103
|
return False
|
|
104
|
-
previous =
|
|
104
|
+
previous = resolve_field_path(original_instance, self.field)
|
|
105
105
|
return previous != self.value and current == self.value
|
|
106
106
|
else:
|
|
107
107
|
return current == self.value
|
|
@@ -116,8 +116,8 @@ class HasChanged(HookCondition):
|
|
|
116
116
|
if not original_instance:
|
|
117
117
|
return False
|
|
118
118
|
|
|
119
|
-
current =
|
|
120
|
-
previous =
|
|
119
|
+
current = resolve_field_path(instance, self.field)
|
|
120
|
+
previous = resolve_field_path(original_instance, self.field)
|
|
121
121
|
|
|
122
122
|
return (current != previous) == self.has_changed
|
|
123
123
|
|
|
@@ -135,9 +135,9 @@ class WasEqual(HookCondition):
|
|
|
135
135
|
def check(self, instance, original_instance=None):
|
|
136
136
|
if original_instance is None:
|
|
137
137
|
return False
|
|
138
|
-
previous =
|
|
138
|
+
previous = resolve_field_path(original_instance, self.field)
|
|
139
139
|
if self.only_on_change:
|
|
140
|
-
current =
|
|
140
|
+
current = resolve_field_path(instance, self.field)
|
|
141
141
|
return previous == self.value and current != self.value
|
|
142
142
|
else:
|
|
143
143
|
return previous == self.value
|
|
@@ -155,8 +155,8 @@ class ChangesTo(HookCondition):
|
|
|
155
155
|
def check(self, instance, original_instance=None):
|
|
156
156
|
if original_instance is None:
|
|
157
157
|
return False
|
|
158
|
-
previous =
|
|
159
|
-
current =
|
|
158
|
+
previous = resolve_field_path(original_instance, self.field)
|
|
159
|
+
current = resolve_field_path(instance, self.field)
|
|
160
160
|
return previous != self.value and current == self.value
|
|
161
161
|
|
|
162
162
|
|
|
@@ -166,7 +166,7 @@ class IsGreaterThan(HookCondition):
|
|
|
166
166
|
self.value = value
|
|
167
167
|
|
|
168
168
|
def check(self, instance, original_instance=None):
|
|
169
|
-
current =
|
|
169
|
+
current = resolve_field_path(instance, self.field)
|
|
170
170
|
return current is not None and current > self.value
|
|
171
171
|
|
|
172
172
|
|
|
@@ -176,7 +176,7 @@ class IsGreaterThanOrEqual(HookCondition):
|
|
|
176
176
|
self.value = value
|
|
177
177
|
|
|
178
178
|
def check(self, instance, original_instance=None):
|
|
179
|
-
current =
|
|
179
|
+
current = resolve_field_path(instance, self.field)
|
|
180
180
|
return current is not None and current >= self.value
|
|
181
181
|
|
|
182
182
|
|
|
@@ -186,7 +186,7 @@ class IsLessThan(HookCondition):
|
|
|
186
186
|
self.value = value
|
|
187
187
|
|
|
188
188
|
def check(self, instance, original_instance=None):
|
|
189
|
-
current =
|
|
189
|
+
current = resolve_field_path(instance, self.field)
|
|
190
190
|
return current is not None and current < self.value
|
|
191
191
|
|
|
192
192
|
|
|
@@ -196,7 +196,7 @@ class IsLessThanOrEqual(HookCondition):
|
|
|
196
196
|
self.value = value
|
|
197
197
|
|
|
198
198
|
def check(self, instance, original_instance=None):
|
|
199
|
-
current =
|
|
199
|
+
current = resolve_field_path(instance, self.field)
|
|
200
200
|
return current is not None and current <= self.value
|
|
201
201
|
|
|
202
202
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
django_bulk_hooks/__init__.py,sha256=4QlWY5rqR9o2ddrNB-ypM4s1GtNJ1ZvL2ABhybaPpio,1823
|
|
2
2
|
django_bulk_hooks/changeset.py,sha256=WALeiWDcjOBNdCKeidVKOPKAySKj9ZOvUJ-kWaVZYhM,7444
|
|
3
|
-
django_bulk_hooks/conditions.py,sha256=
|
|
3
|
+
django_bulk_hooks/conditions.py,sha256=qtGjToKXC8FPUPK31Mib-GMzc9GSdrH90M2pT3CIsh8,8111
|
|
4
4
|
django_bulk_hooks/constants.py,sha256=PxpEETaO6gdENcTPoXS586lerGKVP3nmjpDvOkmhYxI,509
|
|
5
5
|
django_bulk_hooks/context.py,sha256=mqaC5-yESDTA5ruI7fuXlt8qSgKuOFp0mjq7h1-4HdQ,1926
|
|
6
6
|
django_bulk_hooks/debug_utils.py,sha256=6T32E_Pms6gbCl94A55fJAe_ynFsK_CJBTaPcsG8tik,4578
|
|
@@ -20,7 +20,7 @@ django_bulk_hooks/operations/mti_handler.py,sha256=eIH-tImMqcWR5lLQr6Ca-HeVYta-U
|
|
|
20
20
|
django_bulk_hooks/operations/mti_plans.py,sha256=fHUYbrUAHq8UXqxgAD43oHdTxOnEkmpxoOD4Qrzfqk8,2878
|
|
21
21
|
django_bulk_hooks/queryset.py,sha256=ody4MXrRREL27Ts2ey1UpS0tb5Dxnw-6kN3unxPQ3zY,5860
|
|
22
22
|
django_bulk_hooks/registry.py,sha256=UPerNhtVz_9tKZqrYSZD2LhjAcs4F6hVUuk8L5oOeHc,8821
|
|
23
|
-
django_bulk_hooks-0.2.
|
|
24
|
-
django_bulk_hooks-0.2.
|
|
25
|
-
django_bulk_hooks-0.2.
|
|
26
|
-
django_bulk_hooks-0.2.
|
|
23
|
+
django_bulk_hooks-0.2.8.dist-info/LICENSE,sha256=dguKIcbDGeZD-vXWdLyErPUALYOvtX_fO4Zjhq481uk,1088
|
|
24
|
+
django_bulk_hooks-0.2.8.dist-info/METADATA,sha256=bkF722Ehasysowep-24uwfmkGPCvCcYuVz7v2-kawcM,9264
|
|
25
|
+
django_bulk_hooks-0.2.8.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
|
26
|
+
django_bulk_hooks-0.2.8.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|