From 874c09a8214fc1368310d039087a301a81a5ba47 Mon Sep 17 00:00:00 2001 From: Pradeep Sukhwani Date: Wed, 9 Feb 2022 14:01:14 +0530 Subject: [PATCH 1/4] added support for auto_now=True calling .save_dirty_fields() will also check if any DateTime field has auto_now=True --- src/dirtyfields/dirtyfields.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/dirtyfields/dirtyfields.py b/src/dirtyfields/dirtyfields.py index 49023fa..510593c 100644 --- a/src/dirtyfields/dirtyfields.py +++ b/src/dirtyfields/dirtyfields.py @@ -1,4 +1,5 @@ from copy import deepcopy +from datetime import datetime from django.core.exceptions import ValidationError from django.db.models.expressions import BaseExpression @@ -77,7 +78,10 @@ def _as_dict(self, check_relationship, include_primary_key=True): if field.get_attname() in deferred_fields: continue - field_value = getattr(self, field.attname) + if field.auto_now: + field_value = datetime.now() + else: + field_value = getattr(self, field.attname) # If current field value is an expression, we are not evaluating it if isinstance(field_value, (BaseExpression, Combinable)): From 048ae2be0c1a17eeb8a43116a1c1385bd87e2cc7 Mon Sep 17 00:00:00 2001 From: Pradeep Sukhwani Date: Wed, 9 Feb 2022 17:16:55 +0530 Subject: [PATCH 2/4] added testcases and added check --- src/dirtyfields/dirtyfields.py | 5 ++--- tests/models.py | 5 +++++ tests/test_timezone_aware_fields.py | 9 ++++++++- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/dirtyfields/dirtyfields.py b/src/dirtyfields/dirtyfields.py index 510593c..ac72e42 100644 --- a/src/dirtyfields/dirtyfields.py +++ b/src/dirtyfields/dirtyfields.py @@ -78,10 +78,9 @@ def _as_dict(self, check_relationship, include_primary_key=True): if field.get_attname() in deferred_fields: continue - if field.auto_now: + field_value = getattr(self, field.attname) + if isinstance(field_value, datetime) and field.auto_now: field_value = datetime.now() - else: - field_value = getattr(self, field.attname) # If current field value is an expression, we are not evaluating it if isinstance(field_value, (BaseExpression, Combinable)): diff --git a/tests/models.py b/tests/models.py index b2dd9e9..d62b973 100644 --- a/tests/models.py +++ b/tests/models.py @@ -69,6 +69,11 @@ class DatetimeModelTest(DirtyFieldsMixin, models.Model): datetime_field = models.DateTimeField(default=django_timezone.now) +class UpdatedDatetimeModelTest(DirtyFieldsMixin, models.Model): + # data = models.CharField(max_length=255) + updated_datetime_field = models.DateTimeField(auto_now=True) + + class CurrentDatetimeModelTest(DirtyFieldsMixin, models.Model): compare_function = ( timezone_support_compare, diff --git a/tests/test_timezone_aware_fields.py b/tests/test_timezone_aware_fields.py index 381d68a..1435c21 100644 --- a/tests/test_timezone_aware_fields.py +++ b/tests/test_timezone_aware_fields.py @@ -4,7 +4,7 @@ from django.test.utils import override_settings from django.utils import timezone as django_timezone -from .models import DatetimeModelTest, CurrentDatetimeModelTest +from .models import DatetimeModelTest, CurrentDatetimeModelTest, UpdatedDatetimeModelTest @override_settings(USE_TZ=True) @@ -107,3 +107,10 @@ def test_datetime_fields_with_current_timezone_conversion_without_timezone_suppo ), ): assert tm.get_dirty_fields() == {} + + +@pytest.mark.django_db +def test_updated_datetime_fields(): + tm = UpdatedDatetimeModelTest.objects.create() + tm.id = 2 + assert list(tm.get_dirty_fields().keys()) == ['id', 'updated_datetime_field'] From 76bc3750d32a1f60eb5c1a98a00f29525fdd55e6 Mon Sep 17 00:00:00 2001 From: Pradeep Sukhwani Date: Wed, 9 Feb 2022 17:19:10 +0530 Subject: [PATCH 3/4] code clean-up --- tests/models.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/models.py b/tests/models.py index d62b973..f879593 100644 --- a/tests/models.py +++ b/tests/models.py @@ -70,7 +70,6 @@ class DatetimeModelTest(DirtyFieldsMixin, models.Model): class UpdatedDatetimeModelTest(DirtyFieldsMixin, models.Model): - # data = models.CharField(max_length=255) updated_datetime_field = models.DateTimeField(auto_now=True) From 13937b70f20bea2fbddcbb70e894e02b524ed7fc Mon Sep 17 00:00:00 2001 From: Pradeep Sukhwani Date: Mon, 28 Feb 2022 19:45:49 +0530 Subject: [PATCH 4/4] used built-in timezone to capture the timezone aware datetime object --- src/dirtyfields/dirtyfields.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/dirtyfields/dirtyfields.py b/src/dirtyfields/dirtyfields.py index ac72e42..54ea30f 100644 --- a/src/dirtyfields/dirtyfields.py +++ b/src/dirtyfields/dirtyfields.py @@ -1,10 +1,9 @@ from copy import deepcopy -from datetime import datetime - from django.core.exceptions import ValidationError from django.db.models.expressions import BaseExpression from django.db.models.expressions import Combinable from django.db.models.signals import post_save, m2m_changed +from django.utils import timezone from .compare import raw_compare, compare_states, normalise_value @@ -79,13 +78,14 @@ def _as_dict(self, check_relationship, include_primary_key=True): continue field_value = getattr(self, field.attname) - if isinstance(field_value, datetime) and field.auto_now: - field_value = datetime.now() # If current field value is an expression, we are not evaluating it if isinstance(field_value, (BaseExpression, Combinable)): continue + if isinstance(field_value, timezone.datetime) and field.auto_now: + field_value = timezone.now() + try: # Store the converted value for fields with conversion field_value = field.to_python(field_value)