364 lines
13 KiB
Python
364 lines
13 KiB
Python
"""Main app models."""
|
|
from typing import Iterable
|
|
|
|
from django.conf import settings
|
|
from django.contrib.contenttypes import fields as generic
|
|
from django.contrib.contenttypes.models import ContentType
|
|
from django.contrib.postgres.fields import JSONField
|
|
from django.core.validators import EMPTY_VALUES
|
|
from django.db import models
|
|
from django.db.models import Q
|
|
from django.utils.translation import gettext_lazy as _
|
|
|
|
from configuration.models import TranslationSettings
|
|
from location.models import Country
|
|
from main import methods
|
|
from review.models import Review
|
|
from utils.models import (ProjectBaseMixin, TJSONField, URLImageMixin,
|
|
TranslatedFieldsMixin, PlatformMixin)
|
|
|
|
|
|
class Currency(TranslatedFieldsMixin, models.Model):
|
|
"""Currency model."""
|
|
name = TJSONField(
|
|
_('name'), null=True, blank=True,
|
|
default=None, help_text='{"en-GB":"some text"}')
|
|
sign = models.CharField(_('sign'), max_length=255)
|
|
slug = models.SlugField(max_length=255, unique=True)
|
|
code = models.CharField(max_length=5, unique=True, null=True, default=None)
|
|
|
|
class Meta:
|
|
verbose_name = _('currency')
|
|
verbose_name_plural = _('currencies')
|
|
|
|
def __str__(self):
|
|
return f'{self.name}'
|
|
|
|
|
|
class SiteSettingsQuerySet(models.QuerySet):
|
|
"""Extended queryset for SiteSettings model."""
|
|
|
|
def with_country(self):
|
|
return self.filter(country__isnull=False)
|
|
|
|
def by_country_code(self, code):
|
|
return self.filter(country__code=code)
|
|
|
|
|
|
class SiteSettings(ProjectBaseMixin):
|
|
subdomain = models.CharField(max_length=255, db_index=True, unique=True,
|
|
verbose_name=_('Subdomain'))
|
|
country = models.OneToOneField(Country, on_delete=models.PROTECT,
|
|
null=True, blank=True, default=None,
|
|
verbose_name=_('Country'))
|
|
default_site = models.BooleanField(default=False,
|
|
verbose_name=_('Default site'))
|
|
pinterest_page_url = models.URLField(blank=True, null=True, default=None,
|
|
verbose_name=_('Pinterest page URL'))
|
|
twitter_page_url = models.URLField(blank=True, null=True, default=None,
|
|
verbose_name=_('Twitter page URL'))
|
|
facebook_page_url = models.URLField(blank=True, null=True, default=None,
|
|
verbose_name=_('Facebook page URL'))
|
|
instagram_page_url = models.URLField(blank=True, null=True, default=None,
|
|
verbose_name=_('Instagram page URL'))
|
|
contact_email = models.EmailField(blank=True, null=True, default=None,
|
|
verbose_name=_('Contact email'))
|
|
config = JSONField(blank=True, null=True, default=None,
|
|
verbose_name=_('Config'))
|
|
ad_config = models.TextField(blank=True, null=True, default=None,
|
|
verbose_name=_('AD config'))
|
|
currency = models.ForeignKey(Currency, on_delete=models.PROTECT, null=True, default=None)
|
|
|
|
old_id = models.IntegerField(blank=True, null=True)
|
|
|
|
objects = SiteSettingsQuerySet.as_manager()
|
|
|
|
class Meta:
|
|
"""Meta class."""
|
|
|
|
verbose_name = _('Site setting')
|
|
verbose_name_plural = _('Site settings')
|
|
|
|
def __str__(self):
|
|
return f'ID: "{self.id}". Site: "{self.subdomain}"'
|
|
|
|
@property
|
|
def published_features(self):
|
|
return self.feature_set.filter(sitefeature__site_settings=self,
|
|
sitefeature__published=True)
|
|
|
|
@property
|
|
def published_sitefeatures(self):
|
|
return self.sitefeature_set. \
|
|
filter(Q(published=True) &
|
|
Q(feature__source__in=[PlatformMixin.WEB, PlatformMixin.ALL]))
|
|
|
|
@property
|
|
def site_url(self):
|
|
return methods.site_url(schema=settings.SCHEMA_URI,
|
|
subdomain=self.subdomain,
|
|
domain=settings.SITE_DOMAIN_URI)
|
|
|
|
|
|
class Feature(ProjectBaseMixin, PlatformMixin):
|
|
"""Feature model."""
|
|
|
|
slug = models.SlugField(max_length=255, unique=True)
|
|
priority = models.IntegerField(unique=True, null=True, default=None)
|
|
route = models.ForeignKey('PageType', on_delete=models.PROTECT, null=True, default=None)
|
|
site_settings = models.ManyToManyField(SiteSettings, through='SiteFeature')
|
|
old_id = models.IntegerField(null=True, blank=True)
|
|
|
|
class Meta:
|
|
"""Meta class."""
|
|
verbose_name = _('Feature')
|
|
verbose_name_plural = _('Features')
|
|
|
|
def __str__(self):
|
|
return f'{self.slug}'
|
|
|
|
|
|
class SiteFeatureQuerySet(models.QuerySet):
|
|
"""Extended queryset for SiteFeature model."""
|
|
|
|
def published(self, switcher=True):
|
|
return self.filter(published=switcher)
|
|
|
|
def by_country_code(self, country_code: str):
|
|
return self.filter(site_settings__country__code=country_code)
|
|
|
|
def by_sources(self, sources: Iterable[int]):
|
|
return self.filter(feature__source__in=sources)
|
|
|
|
|
|
class SiteFeature(ProjectBaseMixin):
|
|
"""SiteFeature model."""
|
|
|
|
site_settings = models.ForeignKey(SiteSettings, on_delete=models.CASCADE)
|
|
feature = models.ForeignKey(Feature, on_delete=models.PROTECT)
|
|
published = models.BooleanField(default=False, verbose_name=_('Published'))
|
|
main = models.BooleanField(default=False, verbose_name=_('Main'))
|
|
nested = models.ManyToManyField('self', symmetrical=False)
|
|
old_id = models.IntegerField(null=True, blank=True)
|
|
|
|
objects = SiteFeatureQuerySet.as_manager()
|
|
|
|
class Meta:
|
|
"""Meta class."""
|
|
|
|
verbose_name = _('Site feature')
|
|
verbose_name_plural = _('Site features')
|
|
unique_together = ('site_settings', 'feature')
|
|
|
|
|
|
class Award(TranslatedFieldsMixin, URLImageMixin, models.Model):
|
|
"""Award model."""
|
|
WAITING = 0
|
|
PUBLISHED = 1
|
|
|
|
STATE_CHOICES = (
|
|
(WAITING, 'waiting'),
|
|
(PUBLISHED, 'published')
|
|
)
|
|
|
|
award_type = models.ForeignKey('main.AwardType', on_delete=models.CASCADE)
|
|
title = TJSONField(
|
|
_('title'), null=True, blank=True,
|
|
default=None, help_text='{"en-GB":"some text"}')
|
|
vintage_year = models.CharField(_('vintage year'), max_length=255, default='')
|
|
|
|
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
|
|
object_id = models.PositiveIntegerField()
|
|
content_object = generic.GenericForeignKey('content_type', 'object_id')
|
|
|
|
state = models.PositiveSmallIntegerField(default=WAITING, choices=STATE_CHOICES,
|
|
verbose_name=_('State'))
|
|
|
|
old_id = models.IntegerField(null=True, blank=True)
|
|
|
|
def __str__(self):
|
|
title = 'None'
|
|
lang = TranslationSettings.get_solo().default_language
|
|
if self.title and lang in self.title:
|
|
title = self.title[lang]
|
|
return f'id:{self.id}-{title}'
|
|
|
|
|
|
class AwardType(models.Model):
|
|
"""AwardType model."""
|
|
country = models.ForeignKey(
|
|
'location.Country', verbose_name=_('country'), on_delete=models.CASCADE)
|
|
name = models.CharField(_('name'), max_length=255)
|
|
old_id = models.IntegerField(null=True, blank=True)
|
|
|
|
def __str__(self):
|
|
return self.name
|
|
|
|
|
|
class CarouselQuerySet(models.QuerySet):
|
|
"""Carousel QuerySet."""
|
|
|
|
def is_parsed(self):
|
|
"""Parsed carousel objects."""
|
|
return self.filter(is_parse=True)
|
|
|
|
def active(self):
|
|
"""Active carousel objects."""
|
|
return self.filter(active=True)
|
|
|
|
def by_country_code(self, code):
|
|
"""Filter collection by country code."""
|
|
return self.filter(country__code=code)
|
|
|
|
|
|
class Carousel(models.Model):
|
|
"""Carousel model."""
|
|
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE, blank=True, null=True, default=None)
|
|
object_id = models.PositiveIntegerField(blank=True, null=True, default=None)
|
|
content_object = generic.GenericForeignKey('content_type', 'object_id')
|
|
|
|
old_id = models.PositiveIntegerField(_('old id'), blank=True, null=True, default=None)
|
|
title = models.CharField(_('old title'), max_length=255, blank=True, null=True, default=None)
|
|
link = models.CharField(_('old link'), max_length=255, blank=True, null=True, default=None)
|
|
attachment_suffix_url = models.TextField(_('old attachment_suffix_url'), blank=True, null=True, default=None)
|
|
description = models.CharField(_('old description'), max_length=255, blank=True, null=True, default=None)
|
|
link_title = models.CharField(_('old link_title'), max_length=255, blank=True, null=True, default=None)
|
|
country = models.ForeignKey(
|
|
Country,
|
|
blank=True,
|
|
null=True,
|
|
on_delete=models.SET_NULL,
|
|
verbose_name=_('country')
|
|
)
|
|
active = models.BooleanField(_('old active'), default=False)
|
|
is_parse = models.BooleanField(_('is parse'), default=False)
|
|
|
|
objects = CarouselQuerySet.as_manager()
|
|
|
|
class Meta:
|
|
"""Meta class."""
|
|
verbose_name = _('Carousel')
|
|
verbose_name_plural = _('Carousel')
|
|
|
|
@property
|
|
def name(self):
|
|
# Check if Generic obj has name or title
|
|
if hasattr(self.content_object, 'name'):
|
|
return self.content_object.name
|
|
if hasattr(self.content_object, 'title'):
|
|
return self.content_object.title_translated
|
|
|
|
@property
|
|
def awards(self):
|
|
if hasattr(self.content_object, 'awards'):
|
|
return self.content_object.awards
|
|
|
|
@property
|
|
def vintage_year(self):
|
|
if hasattr(self.content_object, 'reviews'):
|
|
last_review = self.content_object.reviews.by_status(Review.READY).last()
|
|
if last_review:
|
|
return last_review.vintage
|
|
|
|
@property
|
|
def toque_number(self):
|
|
if hasattr(self.content_object, 'toque_number'):
|
|
return self.content_object.toque_number
|
|
|
|
@property
|
|
def public_mark(self):
|
|
if hasattr(self.content_object, 'public_mark'):
|
|
return self.content_object.public_mark
|
|
|
|
@property
|
|
def image_url(self):
|
|
if self.attachment_suffix_url:
|
|
return f'https://s3.eu-central-1.amazonaws.com/gm-test.com/media/{self.attachment_suffix_url}'
|
|
if hasattr(self.content_object, 'image_url'):
|
|
return self.content_object.image_url
|
|
|
|
@property
|
|
def slug(self):
|
|
if hasattr(self.content_object, 'slug'):
|
|
return self.content_object.slug
|
|
|
|
@property
|
|
def the_most_recent_award(self):
|
|
if hasattr(self.content_object, 'the_most_recent_award'):
|
|
return self.content_object.the_most_recent_award
|
|
|
|
@property
|
|
def model_name(self):
|
|
from establishment.models import Establishment
|
|
from news.models import News
|
|
if isinstance(self.content_object, Establishment):
|
|
return self.content_object.establishment_type.index_name
|
|
elif isinstance(self.content_object, News):
|
|
return self.content_type.model
|
|
elif self.link not in EMPTY_VALUES:
|
|
return 'external'
|
|
return None
|
|
|
|
|
|
class PageQuerySet(models.QuerySet):
|
|
"""QuerySet for model Page."""
|
|
|
|
def by_platform(self, platform: int):
|
|
"""Filter by platform."""
|
|
return self.filter(source__in=[Page.ALL, platform])
|
|
|
|
|
|
class Page(URLImageMixin, PlatformMixin, ProjectBaseMixin):
|
|
"""Page model."""
|
|
advertisement = models.ForeignKey('advertisement.Advertisement',
|
|
on_delete=models.PROTECT, null=True,
|
|
related_name='pages',
|
|
verbose_name=_('advertisement'))
|
|
width = models.PositiveIntegerField(null=True,
|
|
verbose_name=_('Block width')) # 300
|
|
height = models.PositiveIntegerField(null=True,
|
|
verbose_name=_('Block height')) # 250
|
|
|
|
objects = PageQuerySet.as_manager()
|
|
|
|
class Meta:
|
|
"""Meta class."""
|
|
verbose_name = _('page')
|
|
verbose_name_plural = _('pages')
|
|
unique_together = ('advertisement', 'source')
|
|
|
|
def __str__(self):
|
|
"""Overridden dunder method."""
|
|
return self.get_source_display()
|
|
|
|
|
|
class PageTypeQuerySet(models.QuerySet):
|
|
"""QuerySet for model PageType."""
|
|
|
|
|
|
class PageType(ProjectBaseMixin):
|
|
"""Page type model."""
|
|
|
|
name = models.CharField(max_length=255, unique=True,
|
|
verbose_name=_('name'))
|
|
|
|
objects = PageTypeQuerySet.as_manager()
|
|
|
|
class Meta:
|
|
"""Meta class."""
|
|
verbose_name = _('page type')
|
|
verbose_name_plural = _('page types')
|
|
|
|
def __str__(self):
|
|
"""Overridden dunder method."""
|
|
return self.name
|
|
|
|
|
|
class Footer(ProjectBaseMixin):
|
|
site = models.ForeignKey(
|
|
'main.SiteSettings', related_name='footers', verbose_name=_('footer'),
|
|
on_delete=models.PROTECT
|
|
)
|
|
about_us = models.TextField(_('about_us'))
|
|
copyright = models.TextField(_('copyright'))
|