From b27932a3ec61cfb41f5740351025967926a8f2fe Mon Sep 17 00:00:00 2001 From: Taib Hayat Date: Tue, 11 Jan 2022 11:06:56 +0200 Subject: [PATCH 01/18] set Subject.updated_at to maximum of updated_at of related models --- .../migrations/0033_subject_updated_at.py | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 castellum/subjects/migrations/0033_subject_updated_at.py diff --git a/castellum/subjects/migrations/0033_subject_updated_at.py b/castellum/subjects/migrations/0033_subject_updated_at.py new file mode 100644 index 000000000..0faeb8929 --- /dev/null +++ b/castellum/subjects/migrations/0033_subject_updated_at.py @@ -0,0 +1,37 @@ +from django.db import migrations, models + + +def migrate_data(apps, schema_editor): + Subject = apps.get_model('subjects', 'Subject') + Contact = apps.get_model('contacts', 'Contact') + # re-implementation of constants from model Participation + UNSUITABLE = 2 + INVITED = 3 + FOLLOWUP_APPOINTED = 4 + + + for subject in Subject.objects.all(): + if not subject.deceased or subject.blocked: + contacted_status = [INVITED, UNSUITABLE, FOLLOWUP_APPOINTED] + if subject.participation_set: + participation_updated_at = max(subject.participation_set.filter( + status__in=contacted_status, + excluded_by_cleanup=False, + ).values_list('updated_at', flat=True)) + else: + participation_updated_at = None + contact_updated_at = Contact.objects.get(subject_uuid=subject.pk).updated_at + most_recent_contact = max(subject.updated_at, contact_updated_at, participation_updated_at) + # needs to be update() in order not to set Subject.updated_at to now + Subject.objects.filter(uuid=subject.uuid).update(updated_at=most_recent_contact) + + +class Migration(migrations.Migration): + + dependencies = [ + ('subjects', '0032_subject_uuid_foreign_key'), + ] + + operations = [ + migrations.RunPython(migrate_data), + ] -- GitLab From 03afcc100f8e73b8649ccfbd1e3c754343aec42a Mon Sep 17 00:00:00 2001 From: Taib Hayat Date: Tue, 11 Jan 2022 12:11:33 +0200 Subject: [PATCH 02/18] add symbolic dependency on contact migration --- castellum/subjects/migrations/0033_subject_updated_at.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/castellum/subjects/migrations/0033_subject_updated_at.py b/castellum/subjects/migrations/0033_subject_updated_at.py index 0faeb8929..d16dcb5f5 100644 --- a/castellum/subjects/migrations/0033_subject_updated_at.py +++ b/castellum/subjects/migrations/0033_subject_updated_at.py @@ -30,6 +30,9 @@ class Migration(migrations.Migration): dependencies = [ ('subjects', '0032_subject_uuid_foreign_key'), + + # this dependency is ineffective because it is about the other database + ('contacts', '0015_contactcreationrequest_message'), ] operations = [ -- GitLab From 953a1a81c47dc62dc180e59f9540e273f540fe2c Mon Sep 17 00:00:00 2001 From: Taib Hayat Date: Tue, 11 Jan 2022 12:40:25 +0200 Subject: [PATCH 03/18] add check if subject.contact exists --- castellum/subjects/migrations/0033_subject_updated_at.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/castellum/subjects/migrations/0033_subject_updated_at.py b/castellum/subjects/migrations/0033_subject_updated_at.py index d16dcb5f5..654cf96e9 100644 --- a/castellum/subjects/migrations/0033_subject_updated_at.py +++ b/castellum/subjects/migrations/0033_subject_updated_at.py @@ -20,7 +20,13 @@ def migrate_data(apps, schema_editor): ).values_list('updated_at', flat=True)) else: participation_updated_at = None - contact_updated_at = Contact.objects.get(subject_uuid=subject.pk).updated_at + + contact = Contact.objects.filter(subject_uuid=subject.pk) + if contact.exists(): + contact_updated_at = Contact.objects.get(subject_uuid=subject.pk).updated_at + else: + contact_updated_at = None + most_recent_contact = max(subject.updated_at, contact_updated_at, participation_updated_at) # needs to be update() in order not to set Subject.updated_at to now Subject.objects.filter(uuid=subject.uuid).update(updated_at=most_recent_contact) -- GitLab From f3f5f4773268c997f4c6d33cd2ba5db1956e0591 Mon Sep 17 00:00:00 2001 From: Taib Hayat Date: Tue, 11 Jan 2022 12:40:34 +0200 Subject: [PATCH 04/18] gardening --- castellum/subjects/migrations/0033_subject_updated_at.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/castellum/subjects/migrations/0033_subject_updated_at.py b/castellum/subjects/migrations/0033_subject_updated_at.py index 654cf96e9..07f73fcbe 100644 --- a/castellum/subjects/migrations/0033_subject_updated_at.py +++ b/castellum/subjects/migrations/0033_subject_updated_at.py @@ -8,11 +8,11 @@ def migrate_data(apps, schema_editor): UNSUITABLE = 2 INVITED = 3 FOLLOWUP_APPOINTED = 4 + contacted_status = [INVITED, UNSUITABLE, FOLLOWUP_APPOINTED] for subject in Subject.objects.all(): if not subject.deceased or subject.blocked: - contacted_status = [INVITED, UNSUITABLE, FOLLOWUP_APPOINTED] if subject.participation_set: participation_updated_at = max(subject.participation_set.filter( status__in=contacted_status, -- GitLab From e2c4308974f0e1e885bffb8c74ff7937e40324da Mon Sep 17 00:00:00 2001 From: Taib Hayat Date: Tue, 11 Jan 2022 12:40:50 +0200 Subject: [PATCH 05/18] test migration --- .../test_0033_subject_updated_at.py | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 castellum/subjects/migrations/test_0033_subject_updated_at.py diff --git a/castellum/subjects/migrations/test_0033_subject_updated_at.py b/castellum/subjects/migrations/test_0033_subject_updated_at.py new file mode 100644 index 000000000..01f0acca0 --- /dev/null +++ b/castellum/subjects/migrations/test_0033_subject_updated_at.py @@ -0,0 +1,29 @@ +import pytest +from model_bakery import baker +from freezegun import freeze_time +from tests.markers import skip_old_migration + + +@pytest.mark.django_db +@skip_old_migration('0.70') +def test_keep_uuid(migrator): + old_state = migrator.apply_initial_migration(('subjects', '0032_subject_uuid_foreign_key')) + Subject = old_state.apps.get_model('subjects', 'Subject') + Study = old_state.apps.get_model('studies', 'Study') + Participation = old_state.apps.get_model('recruitment', 'Participation') + # re-implementation of constant from model Participation + INVITED = 3 + + with freeze_time("1970-01-01 12:00"): + subject = baker.make(Subject) + study = baker.make(Study) + with freeze_time("2000-01-01 12:00"): + participation = baker.make(Participation, subject=subject, study=study, status=INVITED) + + new_state = migrator.apply_tested_migration(('subjects', '0033_subject_updated_at')) + Subject = new_state.apps.get_model('subjects', 'Subject') + subject = Subject.objects.first() + + assert subject.updated_at = participation.updated_at + + migrator.reset() \ No newline at end of file -- GitLab From f0c062627179c0ee02c5f70301de594ab464fceb Mon Sep 17 00:00:00 2001 From: Taib Hayat Date: Tue, 11 Jan 2022 12:59:07 +0200 Subject: [PATCH 06/18] move check for deceased and blocked to database --- .../migrations/0033_subject_updated_at.py | 37 +++++++++---------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/castellum/subjects/migrations/0033_subject_updated_at.py b/castellum/subjects/migrations/0033_subject_updated_at.py index 07f73fcbe..42c3ebe1e 100644 --- a/castellum/subjects/migrations/0033_subject_updated_at.py +++ b/castellum/subjects/migrations/0033_subject_updated_at.py @@ -11,25 +11,24 @@ def migrate_data(apps, schema_editor): contacted_status = [INVITED, UNSUITABLE, FOLLOWUP_APPOINTED] - for subject in Subject.objects.all(): - if not subject.deceased or subject.blocked: - if subject.participation_set: - participation_updated_at = max(subject.participation_set.filter( - status__in=contacted_status, - excluded_by_cleanup=False, - ).values_list('updated_at', flat=True)) - else: - participation_updated_at = None - - contact = Contact.objects.filter(subject_uuid=subject.pk) - if contact.exists(): - contact_updated_at = Contact.objects.get(subject_uuid=subject.pk).updated_at - else: - contact_updated_at = None - - most_recent_contact = max(subject.updated_at, contact_updated_at, participation_updated_at) - # needs to be update() in order not to set Subject.updated_at to now - Subject.objects.filter(uuid=subject.uuid).update(updated_at=most_recent_contact) + for subject in Subject.objects.filter(deceased=False, blocked=False): + if subject.participation_set: + participation_updated_at = max(subject.participation_set.filter( + status__in=contacted_status, + excluded_by_cleanup=False, + ).values_list('updated_at', flat=True)) + else: + participation_updated_at = None + + contact = Contact.objects.filter(subject_uuid=subject.pk) + if contact.exists(): + contact_updated_at = Contact.objects.get(subject_uuid=subject.pk).updated_at + else: + contact_updated_at = None + + most_recent_contact = max(subject.updated_at, contact_updated_at, participation_updated_at) + # needs to be update() in order not to set Subject.updated_at to now + Subject.objects.filter(uuid=subject.uuid).update(updated_at=most_recent_contact) class Migration(migrations.Migration): -- GitLab From 1371ede80a1814ef1469ceb42a7457b1bf4184c8 Mon Sep 17 00:00:00 2001 From: Taib Hayat Date: Tue, 11 Jan 2022 13:00:05 +0200 Subject: [PATCH 07/18] mv participation.updated_at query to database --- .../subjects/migrations/0033_subject_updated_at.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/castellum/subjects/migrations/0033_subject_updated_at.py b/castellum/subjects/migrations/0033_subject_updated_at.py index 42c3ebe1e..633eacbf4 100644 --- a/castellum/subjects/migrations/0033_subject_updated_at.py +++ b/castellum/subjects/migrations/0033_subject_updated_at.py @@ -12,13 +12,10 @@ def migrate_data(apps, schema_editor): for subject in Subject.objects.filter(deceased=False, blocked=False): - if subject.participation_set: - participation_updated_at = max(subject.participation_set.filter( - status__in=contacted_status, - excluded_by_cleanup=False, - ).values_list('updated_at', flat=True)) - else: - participation_updated_at = None + participation_updated_at = subject.participation_set.filter( + status__in=contacted_status, + excluded_by_cleanup=False, + ).aggregate(models.Max('updated_at')) contact = Contact.objects.filter(subject_uuid=subject.pk) if contact.exists(): -- GitLab From a4ab9d8d13007a68dcaf24ed4e0cb4af2a08914b Mon Sep 17 00:00:00 2001 From: Taib Hayat Date: Tue, 11 Jan 2022 13:07:07 +0200 Subject: [PATCH 08/18] fix typo in test --- castellum/subjects/migrations/test_0033_subject_updated_at.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/castellum/subjects/migrations/test_0033_subject_updated_at.py b/castellum/subjects/migrations/test_0033_subject_updated_at.py index 01f0acca0..b9023ab7f 100644 --- a/castellum/subjects/migrations/test_0033_subject_updated_at.py +++ b/castellum/subjects/migrations/test_0033_subject_updated_at.py @@ -24,6 +24,6 @@ def test_keep_uuid(migrator): Subject = new_state.apps.get_model('subjects', 'Subject') subject = Subject.objects.first() - assert subject.updated_at = participation.updated_at + assert subject.updated_at == participation.updated_at migrator.reset() \ No newline at end of file -- GitLab From b470232d38226f18463c3b5f88ead0c10288a675 Mon Sep 17 00:00:00 2001 From: Taib Hayat Date: Tue, 11 Jan 2022 13:17:22 +0200 Subject: [PATCH 09/18] add check for None values --- castellum/subjects/migrations/0033_subject_updated_at.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/castellum/subjects/migrations/0033_subject_updated_at.py b/castellum/subjects/migrations/0033_subject_updated_at.py index 633eacbf4..827f34cad 100644 --- a/castellum/subjects/migrations/0033_subject_updated_at.py +++ b/castellum/subjects/migrations/0033_subject_updated_at.py @@ -23,7 +23,8 @@ def migrate_data(apps, schema_editor): else: contact_updated_at = None - most_recent_contact = max(subject.updated_at, contact_updated_at, participation_updated_at) + dates = [subject.updated_at, contact_updated_at, participation_updated_at] + most_recent_contact = max(date for date in dates if date) # needs to be update() in order not to set Subject.updated_at to now Subject.objects.filter(uuid=subject.uuid).update(updated_at=most_recent_contact) -- GitLab From 81b9ad643ca11e8a9ef8402ff293224e955fa668 Mon Sep 17 00:00:00 2001 From: Taib Hayat Date: Tue, 11 Jan 2022 13:21:58 +0200 Subject: [PATCH 10/18] simplify contact query --- castellum/subjects/migrations/0033_subject_updated_at.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/castellum/subjects/migrations/0033_subject_updated_at.py b/castellum/subjects/migrations/0033_subject_updated_at.py index 827f34cad..05051a5aa 100644 --- a/castellum/subjects/migrations/0033_subject_updated_at.py +++ b/castellum/subjects/migrations/0033_subject_updated_at.py @@ -17,11 +17,9 @@ def migrate_data(apps, schema_editor): excluded_by_cleanup=False, ).aggregate(models.Max('updated_at')) - contact = Contact.objects.filter(subject_uuid=subject.pk) - if contact.exists(): - contact_updated_at = Contact.objects.get(subject_uuid=subject.pk).updated_at - else: - contact_updated_at = None + contact = Contact.objects.filter(subject_uuid=subject.pk).first() + if contact: + contact_updated_at = contact.updated_at dates = [subject.updated_at, contact_updated_at, participation_updated_at] most_recent_contact = max(date for date in dates if date) -- GitLab From 9501bbc741e2ddec777bea77dc2f3636e129356c Mon Sep 17 00:00:00 2001 From: Taib Hayat Date: Tue, 11 Jan 2022 13:23:23 +0200 Subject: [PATCH 11/18] check if dates are erally different before updating --- castellum/subjects/migrations/0033_subject_updated_at.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/castellum/subjects/migrations/0033_subject_updated_at.py b/castellum/subjects/migrations/0033_subject_updated_at.py index 05051a5aa..a365e036e 100644 --- a/castellum/subjects/migrations/0033_subject_updated_at.py +++ b/castellum/subjects/migrations/0033_subject_updated_at.py @@ -24,7 +24,8 @@ def migrate_data(apps, schema_editor): dates = [subject.updated_at, contact_updated_at, participation_updated_at] most_recent_contact = max(date for date in dates if date) # needs to be update() in order not to set Subject.updated_at to now - Subject.objects.filter(uuid=subject.uuid).update(updated_at=most_recent_contact) + if most_recent_contact != subject.updated_at: + Subject.objects.filter(uuid=subject.uuid).update(updated_at=most_recent_contact) class Migration(migrations.Migration): -- GitLab From 934530675a53a2b97d62ac17939294641d70135b Mon Sep 17 00:00:00 2001 From: Taib Hayat Date: Tue, 11 Jan 2022 13:26:15 +0200 Subject: [PATCH 12/18] mv test to correct location --- .../subjects/migrations/test_0033_subject_updated_at.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {castellum => tests}/subjects/migrations/test_0033_subject_updated_at.py (100%) diff --git a/castellum/subjects/migrations/test_0033_subject_updated_at.py b/tests/subjects/migrations/test_0033_subject_updated_at.py similarity index 100% rename from castellum/subjects/migrations/test_0033_subject_updated_at.py rename to tests/subjects/migrations/test_0033_subject_updated_at.py -- GitLab From 6622cd2da573b9c79cd26ef094609a7cb0fe4227 Mon Sep 17 00:00:00 2001 From: Taib Hayat Date: Tue, 11 Jan 2022 15:51:58 +0200 Subject: [PATCH 13/18] datetime to date conversion --- castellum/subjects/migrations/0033_subject_updated_at.py | 2 +- tests/subjects/migrations/test_0033_subject_updated_at.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/castellum/subjects/migrations/0033_subject_updated_at.py b/castellum/subjects/migrations/0033_subject_updated_at.py index a365e036e..c665ee6ed 100644 --- a/castellum/subjects/migrations/0033_subject_updated_at.py +++ b/castellum/subjects/migrations/0033_subject_updated_at.py @@ -21,7 +21,7 @@ def migrate_data(apps, schema_editor): if contact: contact_updated_at = contact.updated_at - dates = [subject.updated_at, contact_updated_at, participation_updated_at] + dates = [subject.updated_at, contact_updated_at, subject.participation_updated_at.date()] most_recent_contact = max(date for date in dates if date) # needs to be update() in order not to set Subject.updated_at to now if most_recent_contact != subject.updated_at: diff --git a/tests/subjects/migrations/test_0033_subject_updated_at.py b/tests/subjects/migrations/test_0033_subject_updated_at.py index b9023ab7f..296780805 100644 --- a/tests/subjects/migrations/test_0033_subject_updated_at.py +++ b/tests/subjects/migrations/test_0033_subject_updated_at.py @@ -24,6 +24,6 @@ def test_keep_uuid(migrator): Subject = new_state.apps.get_model('subjects', 'Subject') subject = Subject.objects.first() - assert subject.updated_at == participation.updated_at + assert subject.updated_at == participation.updated_at.date() migrator.reset() \ No newline at end of file -- GitLab From a97191ad6e988c39ebaf584a1563bce1ddf9ed25 Mon Sep 17 00:00:00 2001 From: Taib Hayat Date: Tue, 11 Jan 2022 15:52:19 +0200 Subject: [PATCH 14/18] allow database access to contact database in test --- tests/subjects/migrations/test_0033_subject_updated_at.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/subjects/migrations/test_0033_subject_updated_at.py b/tests/subjects/migrations/test_0033_subject_updated_at.py index 296780805..b386583c5 100644 --- a/tests/subjects/migrations/test_0033_subject_updated_at.py +++ b/tests/subjects/migrations/test_0033_subject_updated_at.py @@ -4,7 +4,7 @@ from freezegun import freeze_time from tests.markers import skip_old_migration -@pytest.mark.django_db +@pytest.mark.django_db(databases=['default', 'contacts']) @skip_old_migration('0.70') def test_keep_uuid(migrator): old_state = migrator.apply_initial_migration(('subjects', '0032_subject_uuid_foreign_key')) -- GitLab From 47779382f2e0e76b05ad69c345461f6115ba5bc4 Mon Sep 17 00:00:00 2001 From: Taib Hayat Date: Tue, 11 Jan 2022 15:54:02 +0200 Subject: [PATCH 15/18] use annotate() for subject query --- .../migrations/0033_subject_updated_at.py | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/castellum/subjects/migrations/0033_subject_updated_at.py b/castellum/subjects/migrations/0033_subject_updated_at.py index c665ee6ed..5e77f613c 100644 --- a/castellum/subjects/migrations/0033_subject_updated_at.py +++ b/castellum/subjects/migrations/0033_subject_updated_at.py @@ -10,13 +10,18 @@ def migrate_data(apps, schema_editor): FOLLOWUP_APPOINTED = 4 contacted_status = [INVITED, UNSUITABLE, FOLLOWUP_APPOINTED] - - for subject in Subject.objects.filter(deceased=False, blocked=False): - participation_updated_at = subject.participation_set.filter( - status__in=contacted_status, - excluded_by_cleanup=False, - ).aggregate(models.Max('updated_at')) - + subjects = Subject.objects.filter( + deceased=False, blocked=False + ).annotate( + participation_updated_at=models.Max( + 'participation__updated_at', + filter=models.Q( + participation__status__in=[INVITED, UNSUITABLE, FOLLOWUP_APPOINTED], + participation__excluded_by_cleanup=False, + ) + ) + ) + for subject in subjects: contact = Contact.objects.filter(subject_uuid=subject.pk).first() if contact: contact_updated_at = contact.updated_at -- GitLab From 8f59a06b8832dca53bc41dbca564e84aad32c943 Mon Sep 17 00:00:00 2001 From: Taib Hayat Date: Tue, 11 Jan 2022 15:54:29 +0200 Subject: [PATCH 16/18] add case for nonexisting contact --- castellum/subjects/migrations/0033_subject_updated_at.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/castellum/subjects/migrations/0033_subject_updated_at.py b/castellum/subjects/migrations/0033_subject_updated_at.py index 5e77f613c..eaeebc8ae 100644 --- a/castellum/subjects/migrations/0033_subject_updated_at.py +++ b/castellum/subjects/migrations/0033_subject_updated_at.py @@ -25,6 +25,8 @@ def migrate_data(apps, schema_editor): contact = Contact.objects.filter(subject_uuid=subject.pk).first() if contact: contact_updated_at = contact.updated_at + else: + contact_updated_at = None dates = [subject.updated_at, contact_updated_at, subject.participation_updated_at.date()] most_recent_contact = max(date for date in dates if date) -- GitLab From 89322724645aa5839008711bd426a7bfdac74130 Mon Sep 17 00:00:00 2001 From: Taib Hayat Date: Tue, 11 Jan 2022 15:54:36 +0200 Subject: [PATCH 17/18] gardening --- tests/subjects/migrations/test_0033_subject_updated_at.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/subjects/migrations/test_0033_subject_updated_at.py b/tests/subjects/migrations/test_0033_subject_updated_at.py index b386583c5..f269b0cd8 100644 --- a/tests/subjects/migrations/test_0033_subject_updated_at.py +++ b/tests/subjects/migrations/test_0033_subject_updated_at.py @@ -26,4 +26,4 @@ def test_keep_uuid(migrator): assert subject.updated_at == participation.updated_at.date() - migrator.reset() \ No newline at end of file + migrator.reset() -- GitLab From d0c6525b83213bfa4be5d49b9ee729f4dfa9618e Mon Sep 17 00:00:00 2001 From: Tobias Bengfort Date: Tue, 11 Jan 2022 15:18:54 +0100 Subject: [PATCH 18/18] Gardening --- castellum/subjects/migrations/0033_subject_updated_at.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/castellum/subjects/migrations/0033_subject_updated_at.py b/castellum/subjects/migrations/0033_subject_updated_at.py index eaeebc8ae..179a9ae09 100644 --- a/castellum/subjects/migrations/0033_subject_updated_at.py +++ b/castellum/subjects/migrations/0033_subject_updated_at.py @@ -4,11 +4,11 @@ from django.db import migrations, models def migrate_data(apps, schema_editor): Subject = apps.get_model('subjects', 'Subject') Contact = apps.get_model('contacts', 'Contact') + # re-implementation of constants from model Participation UNSUITABLE = 2 INVITED = 3 FOLLOWUP_APPOINTED = 4 - contacted_status = [INVITED, UNSUITABLE, FOLLOWUP_APPOINTED] subjects = Subject.objects.filter( deceased=False, blocked=False @@ -21,6 +21,7 @@ def migrate_data(apps, schema_editor): ) ) ) + for subject in subjects: contact = Contact.objects.filter(subject_uuid=subject.pk).first() if contact: @@ -30,8 +31,9 @@ def migrate_data(apps, schema_editor): dates = [subject.updated_at, contact_updated_at, subject.participation_updated_at.date()] most_recent_contact = max(date for date in dates if date) - # needs to be update() in order not to set Subject.updated_at to now + if most_recent_contact != subject.updated_at: + # needs to be update() in order not to set Subject.updated_at to now Subject.objects.filter(uuid=subject.uuid).update(updated_at=most_recent_contact) -- GitLab