From 667fa4b0f080d9e383b25578a95026fec948108d Mon Sep 17 00:00:00 2001 From: Miguel Johnson Date: Thu, 15 Aug 2024 01:18:00 -0400 Subject: [PATCH 1/4] adding an admin action to remove orphaned tags --- taggit/admin.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/taggit/admin.py b/taggit/admin.py index 408a3d42..9470de14 100644 --- a/taggit/admin.py +++ b/taggit/admin.py @@ -19,7 +19,7 @@ class TagAdmin(admin.ModelAdmin): ordering = ["name", "slug"] search_fields = ["name"] prepopulated_fields = {"slug": ["name"]} - actions = ["render_tag_form"] + actions = ["render_tag_form", "remove_orphaned_tags_action"] def get_urls(self): urls = super().get_urls() @@ -84,3 +84,9 @@ def merge_tags_view(self, request): "selected_tag_ids": selected_tag_ids, } return render(request, "admin/taggit/merge_tags_form.html", context) + + @admin.action(description="Remove orphaned tags") + def remove_orphaned_tags_action(self, request, queryset): + orphaned_tags = Tag.objects.filter(taggit_taggeditem_items=None) + count, _ = orphaned_tags.delete() + self.message_user(request, f"Successfully removed {count} orphaned tags.", level="success") \ No newline at end of file From f19f804c0ae8911e8563783985defc09779cd288 Mon Sep 17 00:00:00 2001 From: Miguel Johnson Date: Thu, 15 Aug 2024 01:26:35 -0400 Subject: [PATCH 2/4] add some error handling --- taggit/admin.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/taggit/admin.py b/taggit/admin.py index 9470de14..1ab26989 100644 --- a/taggit/admin.py +++ b/taggit/admin.py @@ -87,6 +87,9 @@ def merge_tags_view(self, request): @admin.action(description="Remove orphaned tags") def remove_orphaned_tags_action(self, request, queryset): - orphaned_tags = Tag.objects.filter(taggit_taggeditem_items=None) - count, _ = orphaned_tags.delete() - self.message_user(request, f"Successfully removed {count} orphaned tags.", level="success") \ No newline at end of file + try: + orphaned_tags = Tag.objects.filter(taggit_taggeditem_items=None) + count, _ = orphaned_tags.delete() + self.message_user(request, f"Successfully removed {count} orphaned tags.", level="success") + except Exception as e: + self.message_user(request, f"An error occurred: {e}", level="error") \ No newline at end of file From 5004696eda8c663917e3542e273c011b78b3f7a4 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 15 Aug 2024 05:28:17 +0000 Subject: [PATCH 3/4] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- taggit/admin.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/taggit/admin.py b/taggit/admin.py index 1ab26989..611efa16 100644 --- a/taggit/admin.py +++ b/taggit/admin.py @@ -90,6 +90,8 @@ def remove_orphaned_tags_action(self, request, queryset): try: orphaned_tags = Tag.objects.filter(taggit_taggeditem_items=None) count, _ = orphaned_tags.delete() - self.message_user(request, f"Successfully removed {count} orphaned tags.", level="success") + self.message_user( + request, f"Successfully removed {count} orphaned tags.", level="success" + ) except Exception as e: - self.message_user(request, f"An error occurred: {e}", level="error") \ No newline at end of file + self.message_user(request, f"An error occurred: {e}", level="error") From 2181a42b7985dfd88ba5f57c6bb01b7bde377ee4 Mon Sep 17 00:00:00 2001 From: Raphael Gaschignard Date: Wed, 9 Oct 2024 13:58:24 +1000 Subject: [PATCH 4/4] Add an orphaned queryset method to Tags --- CHANGELOG.rst | 2 ++ taggit/admin.py | 2 +- taggit/management/commands/remove_orphaned_tags.py | 2 +- taggit/models.py | 9 +++++++++ 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index eefdd7b8..6a3ced30 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -4,6 +4,8 @@ Changelog (Unreleased) ~~~~~~~~~~~~ +* Add an admin command to remove orphaned tags + 6.1.0 (2024-09-29) ~~~~~~~~~~~~~~~~~~ diff --git a/taggit/admin.py b/taggit/admin.py index 611efa16..7d0847bb 100644 --- a/taggit/admin.py +++ b/taggit/admin.py @@ -88,7 +88,7 @@ def merge_tags_view(self, request): @admin.action(description="Remove orphaned tags") def remove_orphaned_tags_action(self, request, queryset): try: - orphaned_tags = Tag.objects.filter(taggit_taggeditem_items=None) + orphaned_tags = queryset.objects.orphaned() count, _ = orphaned_tags.delete() self.message_user( request, f"Successfully removed {count} orphaned tags.", level="success" diff --git a/taggit/management/commands/remove_orphaned_tags.py b/taggit/management/commands/remove_orphaned_tags.py index 1bd799e7..12e89740 100644 --- a/taggit/management/commands/remove_orphaned_tags.py +++ b/taggit/management/commands/remove_orphaned_tags.py @@ -7,6 +7,6 @@ class Command(BaseCommand): help = "Remove orphaned tags" def handle(self, *args, **options): - orphaned_tags = Tag.objects.filter(taggit_taggeditem_items=None) + orphaned_tags = Tag.objects.orphaned() count = orphaned_tags.delete() self.stdout.write(f"Successfully removed {count} orphaned tags") diff --git a/taggit/models.py b/taggit/models.py index 091d733b..0b14e7d9 100644 --- a/taggit/models.py +++ b/taggit/models.py @@ -105,7 +105,16 @@ def slugify(self, tag, i=None): return slug +class TagQuerySet(models.QuerySet): + + def orphaned(self): + return self.filter(taggit_taggeditem_items=None) + + class Tag(TagBase): + + objects = NaturalKeyManager.from_queryset(TagQuerySet)() + class Meta: verbose_name = _("tag") verbose_name_plural = _("tags")