Skip to content

Commit 98b6949

Browse files
committed
capture mutable fields changes
1 parent f0d4b0a commit 98b6949

File tree

4 files changed

+31
-1
lines changed

4 files changed

+31
-1
lines changed

django_lifecycle/mixins.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from copy import deepcopy
12
from functools import partial, reduce, lru_cache
23
from inspect import isfunction
34
from typing import Any, List
@@ -81,7 +82,7 @@ def __init__(self, *args, **kwargs):
8182
self._initial_state = self._snapshot_state()
8283

8384
def _snapshot_state(self):
84-
state = self.__dict__.copy()
85+
state = deepcopy(self.__dict__)
8586

8687
for watched_related_field in self._watched_fk_model_fields():
8788
state[watched_related_field] = self._current_value(watched_related_field)
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Generated by Django 5.0b1 on 2024-02-20 11:04
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
("testapp", "0005_modelwithgenericforeignkey"),
10+
]
11+
12+
operations = [
13+
migrations.AddField(
14+
model_name="useraccount",
15+
name="configurations",
16+
field=models.JSONField(default=dict),
17+
),
18+
]

tests/testapp/models.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class UserAccount(LifecycleModel):
3737
has_trial = models.BooleanField(default=False)
3838
organization = models.ForeignKey(Organization, null=True, on_delete=models.SET_NULL)
3939
name_changes = models.IntegerField(default=0)
40+
configurations = models.JSONField(default=dict)
4041

4142
status = models.CharField(
4243
default="active",

tests/testapp/tests/test_mixin.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ def test_snapshot_state(self):
5555
"status": "active",
5656
"organization.name": "Dunder Mifflin",
5757
"name_changes": 0,
58+
"configurations": {},
5859
},
5960
)
6061

@@ -77,6 +78,15 @@ def test_initial_value_if_field_has_changed(self):
7778
self.assertFalse(user_account.has_changed("username"))
7879
user_account.username = "Josephine"
7980
self.assertEqual(user_account.initial_value("username"), "Joe")
81+
82+
def test_initial_value_if_mutable_field_has_changed(self):
83+
data = self.stub_data
84+
UserAccount.objects.create(**data)
85+
user_account = UserAccount.objects.get()
86+
self.assertFalse(user_account.has_changed("configurations"))
87+
user_account.configurations['notifications'] = True
88+
self.assertTrue(user_account.has_changed("configurations"))
89+
self.assertEqual(user_account.initial_value("configurations"), {})
8090

8191
def test_initial_value_if_field_has_not_changed(self):
8292
data = self.stub_data

0 commit comments

Comments
 (0)