"""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 TJSONField, TranslatedFieldsMixin 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 order_by_priority(self): return self.order_by('chosentagsettings__priority') class Tag(TranslatedFieldsMixin, models.Model): """Tag model.""" label = TJSONField(blank=True, null=True, default=None, verbose_name=_('label'), help_text='{"en-GB":"some text"}') value = models.CharField(_('indexing name'), max_length=255, blank=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') 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.label_translated})' class ChosenTagSettingsQuerySet(models.QuerySet): def by_country_code(self, country_code): return self.filter(country__code=country_code) class ChosenTagSettings(models.Model): """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 = _('Tag') verbose_name_plural = _('Tags') class TagCategoryQuerySet(models.QuerySet): """Extended queryset for TagCategory model.""" def with_base_related(self): """Select related objects.""" return self.prefetch_related('tags') 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=True) 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 with_tags(self, switcher=True): """Filter by existing tags.""" return self.exclude(tags__isnull=switcher) class TagCategory(TranslatedFieldsMixin, models.Model): """Tag base category model.""" STRING = 'string' LIST = 'list' INTEGER = 'integer' VALUE_TYPE_CHOICES = ( (STRING, _('string')), (LIST, _('list')), (INTEGER, _('integer')), ) label = TJSONField(blank=True, null=True, default=None, verbose_name=_('label'), help_text='{"en-GB":"some text"}') country = models.ForeignKey('location.Country', on_delete=models.SET_NULL, 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, ) objects = TagCategoryQuerySet.as_manager() class Meta: """Meta class.""" verbose_name = _('Tag category') verbose_name_plural = _('Tag categories') def __str__(self): label = 'None' lang = TranslationSettings.get_solo().default_language if self.label and lang in self.label: label = self.label[lang] return f'id:{self.id}-{label}'