djangodjango-taggitgeneric-foreign-keydjango-generic-relations

How to filter taggit tags with related items fields using the Django ORM?


I have a model where I use the django-taggit TaggableManager:

from django.db import models

from model_utils import Choices
from taggit_autosuggest.managers import TaggableManager


LANGUAGE_CHOICES = Choices(
    ('de', 'Allemand - Deutch'),
    ('en', 'Anglais - English'),
    ('es', 'Espagnol - Español'),
    ('fr', 'Français'),
    ('it', 'Italien - Italiano'),
    ('jp', 'Japonais - 日本語'),
    ('ko', 'Coréen - 한국어'),
    ('pt', 'Portugais - Português'),
    ('th', 'Thaï - ไทย'),
    ('vi', 'Vietnamien - Tiếng Việt'),
    ('zh', 'Chinois - 中文'),
)


class Recipe(models.Model):
    language = language = models.CharField(
        max_length=5,
        choices=LANGUAGE_CHOICES,
        default=LANGUAGE_CHOICES.en
    )
    tags = tags = TaggableManager(
        help_text="Use tab to add a new term.",
        blank=True
    )

How can I grab all the recipes tags with their related recipe language?


Solution

  • After investigation a little bit, I came up with the following solution:

    Add a GenericRelation to the Recipe model:

    from django.contrib.contenttypes.fields import GenericRelation
    from django.db import models
    
    from model_utils import Choices
    from taggit_autosuggest.managers import TaggableManager
    from taggit.models import TaggedItem
    
    
    LANGUAGE_CHOICES = Choices(
        ('de', 'Allemand - Deutch'),
        ('en', 'Anglais - English'),
        ('es', 'Espagnol - Español'),
        ('fr', 'Français'),
        ('it', 'Italien - Italiano'),
        ('jp', 'Japonais - 日本語'),
        ('ko', 'Coréen - 한국어'),
        ('pt', 'Portugais - Português'),
        ('th', 'Thaï - ไทย'),
        ('vi', 'Vietnamien - Tiếng Việt'),
        ('zh', 'Chinois - 中文'),
    )
    
    
    class Recipe(models.Model):
        language = language = models.CharField(
            max_length=5,
            choices=LANGUAGE_CHOICES,
            default=LANGUAGE_CHOICES.en
        )
        tags = tags = TaggableManager(
            help_text="Use tab to add a new term.",
            blank=True
        )
    
        related_tags = GenericRelation(TaggedItem, related_query_name='recipes')
    

    Then you can use the TaggedItem to create your request:

    from taggit.models import TaggedItem
    from django.db.models import Count
    
    tags = TaggedItem.objects \
        .filter(content_type__app_label='recipes') \
        .values_list('tag__name', 'recipes__language') \
        .annotate(dcount=Count('tag_id', 'recipes__language'))