pythondjangodjango-taggit

How to have two tag fields i.e. two Taggable Managers in the same model?


I have a model for uploaded files and I now need to have two tag fields in that model. One for user tags and one for admin tags. I've tried several solutions but neither worked.

Here is my code now and it doesn't work. Not sure if this is to create two separate tables, one for user tags and for admin tags so any help would be appreciated. Also, if you could maybe explain to me what I'm doing because I'm lost.

class UserTags(CommonGenericTaggedItemBase, TaggedItemBase):
    object_id = models.CharField(max_length=50, db_index=True)
    objects = models.Manager()

class BaseTag(TagBase):
    pass


class AdminTags(CommonGenericTaggedItemBase, TaggableManager):
    object_id = models.CharField(max_length=50, db_index=True)
    tag = models.ForeignKey(BaseTag, on_delete=models.CASCADE)
    objects = models.Manager()


# Model for all uploaded files
class Uploaded(models.Model):
    objects: models.Manager()
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="users")
    time_uploaded = models.DateTimeField(auto_now_add=True)
    name = models.CharField(max_length=50)
    file = models.FileField(upload_to=MEDIA_ROOT)
    tag = TaggableManager(blank=True, through=UserTags, related_name='user_tags')
    tags = TaggableManager(blank=True, through=AdminTags, related_name='admin_tags')
    additional_description = models.CharField(max_length=50, blank=True)

    def __str__(self):
        return f"{self.name} {self.file}"

Solution

  • I would try to implement it like this.

    from django.db import models
    from taggit.managers import TaggableManager
    from taggit.models import TaggedItemBase, ItemBase
    
    
    class AdminTag(ItemBase):
        pass
    
    
    class UserTag(ItemBase):
        pass
    
    
    class ThroughAdminTag(TaggableManager):
        content_object = models.ForeignKey('AdminTag', on_delete=models.CASCADE)
    
    
    class ThroughUserTag(TaggableManager):
        content_object = models.ForeignKey('UserTag', on_delete=models.CASCADE)
    
    
    # Model for all uploaded files
    class Uploaded(models.Model):
        objects = models.Manager()
        user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="users")
        time_uploaded = models.DateTimeField(auto_now_add=True)
        name = models.CharField(max_length=50)
        file = models.FileField(upload_to=MEDIA_ROOT)
        tag = TaggableManager(blank=True, through=ThroughUserTag, related_name='user_tags')
        tags = TaggableManager(blank=True, through=ThroughAdminTag, related_name='admin_tags')
        additional_description = models.CharField(max_length=50, blank=True)
    
        def __str__(self):
            return f"{self.name} {self.file}"
    
    

    Not sure whether AdminTag and UserTag need any fields. Inheriting them from ItemBase should, in theory, cover that.