"""Tag app models.""" from django.contrib.contenttypes.models import ContentType from django.db import models from django.utils.translation import gettext_lazy as _ from configuration.models import TranslationSettings from location.models import Country from utils.models import IndexJSON class TagQuerySet(models.QuerySet): def for_news(self): """Select chosen tags for news.""" return self.filter(category__news_types__isnull=False) def for_establishments(self): """Select chosen tags for establishments.""" return self.filter(models.Q(category__establishment_types__isnull=False) | models.Q(category__establishment_subtypes__isnull=False)) def by_category_index_name(self, index_name): return self.filter(category__index_name=index_name) def order_by_priority(self): return self.order_by('chosentagsettings__priority') def by_establishment_type(self, index_name): return self.filter(category__establishment_types__index_name=index_name) class Tag(models.Model): """Tag model.""" value = models.CharField(_('indexing name'), max_length=255, blank=True, db_index=True, null=True, default=None) category = models.ForeignKey('TagCategory', on_delete=models.CASCADE, null=True, related_name='tags', verbose_name=_('Category')) chosen_tag_settings = models.ManyToManyField(Country, through='ChosenTagSettings') priority = models.PositiveIntegerField(null=True, default=0) # It does not make sense since in the old base another structure with duplicates old_id = models.PositiveIntegerField(_('old id'), blank=True, null=True, default=None) old_id_meta_product = models.PositiveIntegerField(_('old id metadata product'), blank=True, null=True, default=None) translation = models.ForeignKey('translation.SiteInterfaceDictionary', on_delete=models.SET_NULL, null=True, related_name='tag', verbose_name=_('Translation')) @property def label_indexing(self): base_dict = self.translation.text if self.translation and isinstance(self.translation.text, dict) else {} index = IndexJSON() for k, v in base_dict.items(): setattr(index, k, v) return index objects = TagQuerySet.as_manager() class Meta: """Meta class.""" verbose_name = _('Tag') verbose_name_plural = _('Tags') def __str__(self): return f'Tag (id = {self.id}, label_translated = {self.value})' class ChosenTagSettingsQuerySet(models.QuerySet): def by_country_code(self, country_code): return self.filter(country__code=country_code) class ChosenTagSettings(models.Model): """Chosen tag model.""" tag = models.ForeignKey(Tag, on_delete=models.PROTECT) country = models.ForeignKey(Country, on_delete=models.PROTECT) priority = models.IntegerField(null=False, default=0) objects = ChosenTagSettingsQuerySet.as_manager() class Meta: """Meta class.""" verbose_name = _('Chosen tag') verbose_name_plural = _('Chosen tags') class TagCategoryQuerySet(models.QuerySet): """Extended queryset for TagCategory model.""" def with_base_related(self): """Select related objects.""" return self.prefetch_related('tags', 'tags__translation').select_related('translation') def with_extended_related(self): """Select related objects.""" return self.select_related('country') def for_news(self): """Select tag categories for news.""" return self.filter(news_types__isnull=False) def for_establishments(self): """Select tag categories for establishments.""" return self.filter(models.Q(establishment_types__isnull=False) | models.Q(establishment_subtypes__isnull=False)) def by_establishment_type(self, index_name): """Filter by establishment type index name.""" return self.filter(establishment_types__index_name=index_name) def by_product_type(self, index_name): """Filter by product type index name.""" return self.filter(tags__products__product_type__index_name=index_name) def wine_tags_category(self): return self.filter(index_name='wine-color') def with_tags(self, switcher=True): """Filter by existing tags.""" return self.exclude(tags__isnull=switcher) class TagCategory(models.Model): """Tag base category model.""" STRING = 'string' LIST = 'list' INTEGER = 'integer' FLOAT = 'float' PERCENTAGE = 'percentage' BOOLEAN = 'bool' VALUE_TYPE_CHOICES = ( (STRING, _('string')), (LIST, _('list')), (INTEGER, _('integer')), (FLOAT, _('float')), (PERCENTAGE, _('percentage')), (BOOLEAN, _('boolean')), ) country = models.ForeignKey('location.Country', on_delete=models.SET_NULL, blank=True, null=True, default=None) public = models.BooleanField(default=False) index_name = models.CharField(max_length=255, blank=True, null=True, verbose_name=_('indexing name'), unique=True) value_type = models.CharField(_('value type'), max_length=255, choices=VALUE_TYPE_CHOICES, default=LIST, ) old_id = models.IntegerField(blank=True, null=True) translation = models.OneToOneField('translation.SiteInterfaceDictionary', on_delete=models.SET_NULL, null=True, related_name='tag_category', verbose_name=_('Translation')) @property def label_indexing(self): base_dict = self.translation.text if self.translation and isinstance(self.translation.text, dict) else {} index = IndexJSON() for k, v in base_dict.items(): setattr(index, k, v) return index objects = TagCategoryQuerySet.as_manager() class Meta: """Meta class.""" verbose_name = _('Tag category') verbose_name_plural = _('Tag categories') def __str__(self): return self.index_name