From 4226e7bd51143c0807b9a9e6ed47c7285303909e Mon Sep 17 00:00:00 2001 From: mailynmailyn Date: Wed, 13 Aug 2025 11:25:25 -0400 Subject: [PATCH 01/13] feat: create `deleted` boolean flag for instrument name - indicates a name has been deleted but preserves in the db refs: #340 --- web-app/django/VIM/apps/instruments/models/instrument_name.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/web-app/django/VIM/apps/instruments/models/instrument_name.py b/web-app/django/VIM/apps/instruments/models/instrument_name.py index b31af750..d180639b 100644 --- a/web-app/django/VIM/apps/instruments/models/instrument_name.py +++ b/web-app/django/VIM/apps/instruments/models/instrument_name.py @@ -34,6 +34,10 @@ class InstrumentName(models.Model): default=False, help_text="Is this name already on Wikidata?", ) + deleted = models.BooleanField( + default=False, + help_text="Soft delete flag. If true, this name is considered deleted but retained in the database.", + ) # Custom validation to ensure at most one UMIL label per instrument language class Meta: From 659995a7438c9389f1f81c7d287f7ad5d6ae80f0 Mon Sep 17 00:00:00 2001 From: mailynmailyn Date: Wed, 13 Aug 2025 12:08:03 -0400 Subject: [PATCH 02/13] feat: set `deleted` status as `true` when the user "deletes" a instrument name from UMIL - allow admin to filter instrument names by deletion status - change deletion UI message to better reflect that the name will persist on the the UMILdb - only display instrument names that are `deleted`=`false` - create migration file refs: #340 --- web-app/django/VIM/apps/instruments/admin.py | 2 +- .../migrations/0010_instrumentname_deleted.py | 20 +++++++++++++++++++ .../instruments/views/instrument_detail.py | 9 ++++++--- .../apps/instruments/views/update_umil_db.py | 4 +++- .../instruments/includes/deleteName.html | 2 +- 5 files changed, 31 insertions(+), 6 deletions(-) create mode 100644 web-app/django/VIM/apps/instruments/migrations/0010_instrumentname_deleted.py diff --git a/web-app/django/VIM/apps/instruments/admin.py b/web-app/django/VIM/apps/instruments/admin.py index fa511e3c..d07d8244 100644 --- a/web-app/django/VIM/apps/instruments/admin.py +++ b/web-app/django/VIM/apps/instruments/admin.py @@ -8,7 +8,7 @@ @admin.register(InstrumentName) class InstrumentNameAdmin(admin.ModelAdmin): - list_filter = ("verification_status", "on_wikidata") # Filter by status + list_filter = ("verification_status", "on_wikidata", "deleted") # Filter by status search_fields = ( "name", "source_name", diff --git a/web-app/django/VIM/apps/instruments/migrations/0010_instrumentname_deleted.py b/web-app/django/VIM/apps/instruments/migrations/0010_instrumentname_deleted.py new file mode 100644 index 00000000..b5b88164 --- /dev/null +++ b/web-app/django/VIM/apps/instruments/migrations/0010_instrumentname_deleted.py @@ -0,0 +1,20 @@ +# Generated by Django 4.2.5 on 2025-08-13 15:20 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("instruments", "0009_alter_instrumentname_verification_status"), + ] + + operations = [ + migrations.AddField( + model_name="instrumentname", + name="deleted", + field=models.BooleanField( + default=False, + help_text="Soft delete flag. If true, this name is considered deleted but retained in the database.", + ), + ), + ] diff --git a/web-app/django/VIM/apps/instruments/views/instrument_detail.py b/web-app/django/VIM/apps/instruments/views/instrument_detail.py index edc674ba..e79aef22 100644 --- a/web-app/django/VIM/apps/instruments/views/instrument_detail.py +++ b/web-app/django/VIM/apps/instruments/views/instrument_detail.py @@ -15,10 +15,13 @@ class InstrumentDetail(DetailView): def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - # Query the instrument names in all languages - instrument_names = context["instrument"].instrumentname_set.select_related( - "language" + # Query the instrument names in all languages, excluding deleted names + instrument_names = ( + context["instrument"] + .instrumentname_set.select_related("language") + .filter(deleted=False) ) + if self.request.user.is_authenticated: # Show all names for authenticated users context["instrument_names"] = instrument_names.all() diff --git a/web-app/django/VIM/apps/instruments/views/update_umil_db.py b/web-app/django/VIM/apps/instruments/views/update_umil_db.py index 1a2ed493..e8d148cf 100644 --- a/web-app/django/VIM/apps/instruments/views/update_umil_db.py +++ b/web-app/django/VIM/apps/instruments/views/update_umil_db.py @@ -133,7 +133,9 @@ def delete_name(request: HttpRequest) -> JsonResponse: # If user is a superuser or created the name, allow deletion if request.user.is_superuser or instrument_name.contributor == request.user: - instrument_name.delete() + instrument_name.deleted = True # Soft delete the name + instrument_name.save() # Don't forget to save the changes + return JsonResponse( { "status": "success", diff --git a/web-app/django/VIM/templates/instruments/includes/deleteName.html b/web-app/django/VIM/templates/instruments/includes/deleteName.html index 1bdc2b61..6d375d45 100644 --- a/web-app/django/VIM/templates/instruments/includes/deleteName.html +++ b/web-app/django/VIM/templates/instruments/includes/deleteName.html @@ -20,7 +20,7 @@