Search code examples
djangodjango-modelsdjango-taggit

Extending TagBase in Django-Taggit


I have created the following TagBase and each category can have subcategory... Will this work? How can I override its add function in the TaggableManager?

 class Category(TagBase):
        parent = models.ForeignKey('self', blank=True, null=True,
                                   related_name='child')
        description = models.TextField(blank=True, help_text="Optional")

        class Meta:
            verbose_name = _('Category')
            verbose_name_plural = _('Categories')

Solution

  • django-taggit/docs/custom_tagging.txt describes how. You must define an intermediary model with a foreign key tag to your TagBase subclass.

    from django.db import models
    from taggit.managers import TaggableManager
    from taggit.models import ItemBase
    
    # Required to create database table connecting your tags to your model.
    class CategorizedEntity(ItemBase):
        content_object = models.ForeignKey('Entity')
        # A ForeignKey that django-taggit looks at to determine the type of Tag
        # e.g. ItemBase.tag_model()
        tag = models.ForeignKey(Category, related_name="%(app_label)s_%(class)s_items")
    
        # Appears one must copy this class method that appears in both TaggedItemBase and GenericTaggedItemBase
        @classmethod
        def tags_for(cls, model, instance=None):
            if instance is not None:
                return cls.tag_model().objects.filter(**{
                    '%s__content_object' % cls.tag_relname(): instance
                })
            return cls.tag_model().objects.filter(**{
                '%s__content_object__isnull' % cls.tag_relname(): False
            }).distinct()
    
    class Entity(models.Model):
        # ... fields here
    
        tags = TaggableManager(through=CategorizedEntity)