Skip to content

Commit 92de9d3

Browse files
authored
Merge pull request #158 from partizaans/fix/refresh-from-db
Update the initial state after calling `refresh_from_db` on the model instance
2 parents cb68490 + 461ed6d commit 92de9d3

File tree

3 files changed

+19
-4
lines changed

3 files changed

+19
-4
lines changed

django_lifecycle/mixins.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,10 @@ def delete(self, *args, **kwargs):
212212
self._run_hooked_methods(AFTER_DELETE, **kwargs)
213213
return value
214214

215+
def refresh_from_db(self, *args, **kwargs):
216+
super().refresh_from_db(*args, **kwargs)
217+
self._initial_state = self._snapshot_state()
218+
215219
@classmethod
216220
@lru_cache(typed=True)
217221
def _potentially_hooked_methods(cls):

docs/advanced.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44

55
These are available on your model instance when the mixin or extend the base model is used.
66

7-
| Method | Details |
8-
|:----------------------------------------:|:-------------------------------------------------------------------------------------------------:|
9-
| `has_changed(field_name: str) -> bool` | Return a boolean indicating whether the field's value has changed since the model was initialized |
10-
| `initial_value(field_name: str) -> bool` | Return the value of the field when the model was first initialized |
7+
| Method | Details |
8+
|:----------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------:|
9+
| `has_changed(field_name: str) -> bool` | Return a boolean indicating whether the field's value has changed since the model was initialized, or refreshed from db |
10+
| `initial_value(field_name: str) -> bool` | Return the value of the field when the model was first initialized, or refreshed from db |
1111

1212
### Example
1313
You can use these methods for more advanced checks, for example:

tests/testapp/tests/test_mixin.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,17 @@ def test_has_changed(self):
203203
user_account.username = "Josephine"
204204
self.assertTrue(user_account.has_changed("username"))
205205

206+
def test_has_changed_when_refreshed_from_db(self):
207+
data = self.stub_data
208+
UserAccount.objects.create(**data)
209+
user_account = UserAccount.objects.get()
210+
UserAccount.objects.update(username="not " + user_account.username)
211+
user_account.refresh_from_db()
212+
user_account.username = data["username"]
213+
self.assertTrue(user_account.has_changed("username"),
214+
'The initial state should get updated after refreshing the object from db')
215+
216+
206217
def test_has_changed_is_true_if_fk_related_model_field_has_changed(self):
207218
org = Organization.objects.create(name="Dunder Mifflin")
208219
UserAccount.objects.create(**self.stub_data, organization=org)

0 commit comments

Comments
 (0)