gault-millau/apps/tag/models.py
2020-01-28 14:54:14 +03:00

201 lines
6.9 KiB
Python

"""Tag app models."""
from django.contrib.contenttypes import fields as generic
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 with_base_related(self):
"""Return QuerySet with base related."""
return self.select_related('category', 'translation')
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
class ChosenTag(models.Model):
"""Chosen tag for type."""
tag = models.ForeignKey(
'Tag', verbose_name=_('tag'), related_name='chosen_tags',
on_delete=models.CASCADE)
site = models.ForeignKey(
'main.SiteSettings', verbose_name=_('site'), on_delete=models.CASCADE)
content_type = models.ForeignKey(
generic.ContentType, on_delete=models.CASCADE)
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey('content_type', 'object_id')
def __str__(self):
return f'chosen_tag:{self.tag}'