django-bulk-hooks 0.1.87__tar.gz → 0.1.89__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.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: django-bulk-hooks
3
- Version: 0.1.87
3
+ Version: 0.1.89
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
@@ -245,15 +245,33 @@ class WasEqual(HookCondition):
245
245
 
246
246
 
247
247
  class HasChanged(HookCondition):
248
- def __init__(self, field):
248
+ def __init__(self, field, has_changed=True):
249
+ """
250
+ Check if a field's value has changed or remained the same.
251
+
252
+ Args:
253
+ field: The field name to check
254
+ has_changed: If True (default), condition passes when field has changed.
255
+ If False, condition passes when field has remained the same.
256
+ This is useful for:
257
+ - Detecting stable/unchanged fields
258
+ - Validating field immutability
259
+ - Ensuring critical fields remain constant
260
+ - State machine validations
261
+ """
249
262
  self.field = field
263
+ self.has_changed = has_changed
250
264
 
251
265
  def check(self, instance, original_instance=None):
252
266
  if original_instance is None:
253
- return True
267
+ # For new instances:
268
+ # - If we're checking for changes (has_changed=True), return False since there's no change yet
269
+ # - If we're checking for stability (has_changed=False), return True since it's technically unchanged
270
+ return not self.has_changed
271
+
254
272
  current_value = resolve_dotted_attr(instance, self.field)
255
273
  original_value = resolve_dotted_attr(original_instance, self.field)
256
- return current_value != original_value
274
+ return (current_value != original_value) == self.has_changed
257
275
 
258
276
  def get_required_fields(self):
259
277
  return {self.field.split('.')[0]}
@@ -52,20 +52,19 @@ def run(model_cls, event, new_instances, original_instances=None, ctx=None):
52
52
  else:
53
53
  handler_instance, func = _handler_cache[handler_key]
54
54
 
55
- # If no condition, process all instances at once
56
- if not condition:
57
- func(new_records=new_instances, old_records=original_instances if any(original_instances) else None)
58
- continue
59
-
60
- # For conditional hooks, filter instances first
61
- to_process_new = []
62
- to_process_old = []
55
+ # Filter instances based on condition
56
+ if condition:
57
+ to_process_new = []
58
+ to_process_old = []
63
59
 
64
- for new, original in zip(new_instances, original_instances, strict=True):
65
- if condition.check(new, original):
66
- to_process_new.append(new)
67
- to_process_old.append(original)
60
+ for new, original in zip(new_instances, original_instances, strict=True):
61
+ if condition.check(new, original):
62
+ to_process_new.append(new)
63
+ to_process_old.append(original)
68
64
 
69
- if to_process_new:
70
- # Call the function with keyword arguments
71
- func(new_records=to_process_new, old_records=to_process_old if any(to_process_old) else None)
65
+ # Only call if we have matching instances
66
+ if to_process_new:
67
+ func(new_records=to_process_new, old_records=to_process_old if any(to_process_old) else None)
68
+ else:
69
+ # No condition, process all instances
70
+ func(new_records=new_instances, old_records=original_instances if any(original_instances) else None)
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "django-bulk-hooks"
3
- version = "0.1.87"
3
+ version = "0.1.89"
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"