Skip to content

Commit

Permalink
Merge pull request #908 from guel-codes/682-orphaned-tags
Browse files Browse the repository at this point in the history
[#682] - Remove Orphaned Tags
  • Loading branch information
rtpg committed Jul 30, 2024
2 parents ffa9d60 + 3b15951 commit d8889a6
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ Changelog

(Unreleased)
~~~~~~~~~~~~
* Added a management command (``remove_orphaned_tags``) to remove orphaned tags

6.0.0 (2024-07-27)
~~~~~~~~~~~~~~~~~~
Expand Down
12 changes: 12 additions & 0 deletions taggit/management/commands/remove_orphaned_tags.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from django.core.management.base import BaseCommand

from taggit.models import Tag


class Command(BaseCommand):
help = "Remove orphaned tags"

def handle(self, *args, **options):
orphaned_tags = Tag.objects.filter(taggit_taggeditem_items=None)
count = orphaned_tags.delete()
self.stdout.write(f"Successfully removed {count} orphaned tags")
58 changes: 58 additions & 0 deletions tests/test_remove_orphaned_tags.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
from django.core.management import call_command
from django.test import TestCase

from taggit.models import Tag
from tests.models import Food, HousePet


class RemoveOrphanedTagsTests(TestCase):
def setUp(self):
# Create some tags, some orphaned and some not
self.orphan_tag1 = Tag.objects.create(name="Orphan1")
self.orphan_tag2 = Tag.objects.create(name="Orphan2")
self.used_tag = Tag.objects.create(name="Used")

# Create instances of Food and HousePet and tag them
self.food_item = Food.objects.create(name="Apple")
self.pet_item = HousePet.objects.create(name="Fido")

self.food_item.tags.add(self.used_tag)
self.pet_item.tags.add(self.used_tag)

def test_remove_orphaned_tags(self):
# Ensure the setup is correct
self.assertEqual(Tag.objects.count(), 3)
self.assertEqual(Tag.objects.filter(taggit_taggeditem_items=None).count(), 2)

# Call the management command to remove orphaned tags
call_command("remove_orphaned_tags")

# Check the count of tags after running the command
self.assertEqual(Tag.objects.count(), 1)
self.assertEqual(Tag.objects.filter(taggit_taggeditem_items=None).count(), 0)

# Ensure that the used tag still exists
self.assertTrue(Tag.objects.filter(name="Used").exists())
self.assertFalse(Tag.objects.filter(name="Orphan1").exists())
self.assertFalse(Tag.objects.filter(name="Orphan2").exists())

def test_no_orphaned_tags(self):
# Ensure the setup is correct
self.assertEqual(Tag.objects.count(), 3)
self.assertEqual(Tag.objects.filter(taggit_taggeditem_items=None).count(), 2)

# Add used_tag to food_item to make no tags orphaned
self.food_item.tags.add(self.orphan_tag1)
self.food_item.tags.add(self.orphan_tag2)

# Call the management command to remove orphaned tags
call_command("remove_orphaned_tags")

# Check the count of tags after running the command
self.assertEqual(Tag.objects.count(), 3)
self.assertEqual(Tag.objects.filter(taggit_taggeditem_items=None).count(), 0)

# Ensure all tags still exist
self.assertTrue(Tag.objects.filter(name="Used").exists())
self.assertTrue(Tag.objects.filter(name="Orphan1").exists())
self.assertTrue(Tag.objects.filter(name="Orphan2").exists())

0 comments on commit d8889a6

Please sign in to comment.