Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update the initial state after calling refresh_from_db on the model instance #158

Merged
merged 1 commit into from
Jun 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions django_lifecycle/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,10 @@ def delete(self, *args, **kwargs):
self._run_hooked_methods(AFTER_DELETE, **kwargs)
return value

def refresh_from_db(self, *args, **kwargs):
super().refresh_from_db(*args, **kwargs)
self._initial_state = self._snapshot_state()

@classmethod
@lru_cache(typed=True)
def _potentially_hooked_methods(cls):
Expand Down
8 changes: 4 additions & 4 deletions docs/advanced.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@

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

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

### Example
You can use these methods for more advanced checks, for example:
Expand Down
11 changes: 11 additions & 0 deletions tests/testapp/tests/test_mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,17 @@ def test_has_changed(self):
user_account.username = "Josephine"
self.assertTrue(user_account.has_changed("username"))

def test_has_changed_when_refreshed_from_db(self):
data = self.stub_data
UserAccount.objects.create(**data)
user_account = UserAccount.objects.get()
UserAccount.objects.update(username="not " + user_account.username)
user_account.refresh_from_db()
user_account.username = data["username"]
self.assertTrue(user_account.has_changed("username"),
'The initial state should get updated after refreshing the object from db')


def test_has_changed_is_true_if_fk_related_model_field_has_changed(self):
org = Organization.objects.create(name="Dunder Mifflin")
UserAccount.objects.create(**self.stub_data, organization=org)
Expand Down