Skip to content

Commit f2c6b80

Browse files
committed
feat: Allow to specify both condition or legacy params
1 parent b658162 commit f2c6b80

File tree

2 files changed

+43
-5
lines changed

2 files changed

+43
-5
lines changed

django_lifecycle/decorators.py

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from __future__ import annotations
22

33
import operator
4+
from django_lifecycle import types
45
from dataclasses import dataclass
56
from functools import reduce
67
from functools import wraps
@@ -23,6 +24,11 @@ class DjangoLifeCycleException(Exception):
2324
@dataclass(order=False)
2425
class HookConfig(Validations):
2526
hook: str
27+
on_commit: bool = False
28+
priority: int = DEFAULT_PRIORITY
29+
condition: Optional[types.Condition] = None
30+
31+
# Legacy parameters
2632
when: Optional[str] = None
2733
when_any: Optional[List[str]] = None
2834
was: Any = "*"
@@ -31,11 +37,28 @@ class HookConfig(Validations):
3137
is_not: Any = NotSet
3238
was_not: Any = NotSet
3339
changes_to: Any = NotSet
34-
on_commit: bool = False
35-
priority: int = DEFAULT_PRIORITY
3640

37-
@property
38-
def condition(self) -> Callable:
41+
def __post_init__(self):
42+
super().__post_init__()
43+
44+
if self.condition is None:
45+
self.condition = self._get_condition_from_legacy_parameters()
46+
47+
def _legacy_parameters_have_been_passed(self) -> bool:
48+
return any(
49+
[
50+
self.when is not None,
51+
self.when_any is not None,
52+
self.was != "*",
53+
self.is_now != "*",
54+
self.has_changed is not None,
55+
self.is_not is not NotSet,
56+
self.was_not is not NotSet,
57+
self.changes_to is not NotSet,
58+
]
59+
)
60+
61+
def _get_condition_from_legacy_parameters(self) -> Callable:
3962
if self.when:
4063
return When(
4164
when=self.when,
@@ -140,9 +163,16 @@ def validate_when_and_when_any(self):
140163
"Can pass either 'when' or 'when_any' but not both"
141164
)
142165

166+
def validate_condition_and_legacy_parameters_are_not_combined(self):
167+
if self.condition is not None and self._legacy_parameters_have_been_passed():
168+
raise DjangoLifeCycleException(
169+
"Legacy parameters (when, when_any, ...) can't be used together with condition"
170+
)
171+
143172
def validate(self):
144173
self.validate_when_and_when_any()
145174
self.validate_on_commit_only_for_after_hooks()
175+
self.validate_condition_and_legacy_parameters_are_not_combined()
146176

147177
def __lt__(self, other):
148178
if not isinstance(other, HookConfig):

tests/testapp/tests/test_decorator.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
from django.test import TestCase
33

44
from django_lifecycle import hook, LifecycleModelMixin, AFTER_CREATE
5+
from django_lifecycle.conditions import Always
6+
from django_lifecycle.decorators import DjangoLifeCycleException
57
from django_lifecycle.priority import HIGHEST_PRIORITY, LOWER_PRIORITY
68

79

@@ -23,7 +25,6 @@ def one_hook(self):
2325

2426
def test_priority_hooks(self):
2527
class FakeModel(LifecycleModelMixin, models.Model):
26-
2728
@hook(AFTER_CREATE)
2829
def mid_priority(self):
2930
pass
@@ -41,3 +42,10 @@ def lowest_priority(self):
4142

4243
expected_method_names = ["top_priority", "mid_priority", "lowest_priority"]
4344
self.assertListEqual(expected_method_names, hooked_method_names)
45+
46+
def test_condition_cannot_be_mixed_with_legacy_parameters(self):
47+
with self.assertRaises(DjangoLifeCycleException):
48+
hook(AFTER_CREATE, condition=Always(), has_changed=True)
49+
50+
def test_no_condition_or_legacy_parameters_is_valid(self):
51+
hook(AFTER_CREATE) # no exception is raised

0 commit comments

Comments
 (0)