from django.contrib.postgres.fields import JSONField from django.contrib.contenttypes.fields import ContentType from django.contrib.contenttypes import fields as generic from django.db import models from django.utils.translation import gettext_lazy as _ from utils.models import ProjectBaseMixin, ImageMixin # Mixins class CollectionNameMixin(models.Model): """CollectionName mixin""" name = models.CharField(_('name'), max_length=250) class Meta: """Meta class""" abstract = True class CollectionDateMixin(models.Model): """CollectionDate mixin""" start = models.DateTimeField(_('start')) end = models.DateTimeField(_('end')) class Meta: """Meta class""" abstract = True # Models class CollectionQuerySet(models.QuerySet): """QuerySet for model Collection""" def by_country_code(self, code): """Filter collection by country code.""" return self.filter(country__code=code) def published(self): """Returned only published collection""" return self.filter(is_publish=True) class Collection(ProjectBaseMixin, CollectionNameMixin, CollectionDateMixin): """Collection model.""" ORDINARY = 0 # Ordinary collection POP = 1 # POP collection COLLECTION_TYPES = ( (ORDINARY, _('Ordinary')), (POP, _('Pop')), ) collection_type = models.PositiveSmallIntegerField(choices=COLLECTION_TYPES, default=ORDINARY, verbose_name=_('Collection type')) image = models.ForeignKey( 'gallery.Image', null=True, blank=True, default=None, verbose_name=_('Collection image'), on_delete=models.CASCADE) is_publish = models.BooleanField( default=False, verbose_name=_('Publish status')) on_top = models.BooleanField( default=False, verbose_name=_('Position on top')) country = models.ForeignKey( 'location.Country', verbose_name=_('country'), on_delete=models.CASCADE) block_size = JSONField( _('collection block properties'), null=True, blank=True, default=None, help_text='{"width": "250px", "height":"250px"}') objects = CollectionQuerySet.as_manager() class Meta: """Meta class.""" verbose_name = _('collection') verbose_name_plural = _('collections') def __str__(self): """String method.""" return f'{self.name}' class CollectionItemQuerySet(models.QuerySet): """QuerySet for model CollectionItem.""" def by_collection(self, collection_id): """Filter by collection id""" return self.filter(collection=collection_id) class CollectionItem(ProjectBaseMixin): """CollectionItem model.""" collection = models.ForeignKey( Collection, verbose_name=_('collection'), on_delete=models.CASCADE) content_type = models.ForeignKey(ContentType, default=None, null=True, blank=True, on_delete=models.CASCADE) object_id = models.PositiveIntegerField(default=None, null=True, blank=True) content_object = generic.GenericForeignKey('content_type', 'object_id') objects = CollectionItemQuerySet.as_manager() class GuideQuerySet(models.QuerySet): """QuerySet for Guide.""" def by_collection_id(self, collection_id): """Filter by collection id""" return self.filter(collection=collection_id) class Guide(ProjectBaseMixin, CollectionNameMixin, CollectionDateMixin): """Guide model.""" parent = models.ForeignKey( 'self', verbose_name=_('parent'), on_delete=models.CASCADE) advertorials = JSONField( _('advertorials'), null=True, blank=True, default=None, help_text='{"key":"value"}') collection = models.ForeignKey( Collection, verbose_name=_('collection'), on_delete=models.CASCADE) objects = GuideQuerySet.as_manager() class Meta: """Meta class.""" verbose_name = _('guide') verbose_name_plural = _('guides') def __str__(self): """String method.""" return f'{self.name}'