"""News app models.""" from django.contrib.contenttypes import fields as generic from django.db import models from django.utils import timezone from django.utils.translation import gettext_lazy as _ from rest_framework.reverse import reverse from utils.models import BaseAttributes, TJSONField, TranslatedFieldsMixin class NewsType(models.Model): """NewsType model.""" name = models.CharField(_('name'), max_length=250) class Meta: """Meta class.""" verbose_name_plural = _('news types') verbose_name = _('news type') def __str__(self): """Overrided __str__ method.""" return self.name class NewsQuerySet(models.QuerySet): """QuerySet for model News""" def by_type(self, news_type): """Filter News by type""" return self.filter(news_type__name=news_type) def by_country_code(self, code): """Filter collection by country code.""" return self.filter(country__code=code) def published(self): """Return only published news""" now = timezone.now() return self.filter(models.Q(models.Q(end__gte=now) | models.Q(end__isnull=True)), is_publish=True, start__lte=now) def with_related(self): """Return qs with related objects.""" return self.select_related('news_type', 'country').prefetch_related('tags') class News(BaseAttributes, TranslatedFieldsMixin): """News model.""" news_type = models.ForeignKey(NewsType, on_delete=models.PROTECT, verbose_name=_('news type')) title = TJSONField(blank=True, null=True, default=None, verbose_name=_('title'), help_text='{"en-GB":"some text"}') subtitle = TJSONField(blank=True, null=True, default=None, verbose_name=_('subtitle'), help_text='{"en-GB":"some text"}') description = TJSONField(blank=True, null=True, default=None, verbose_name=_('description'), help_text='{"en-GB":"some text"}') start = models.DateTimeField(verbose_name=_('Start')) end = models.DateTimeField(blank=True, null=True, default=None, verbose_name=_('End')) slug = models.SlugField(unique=True, max_length=50, null=True, verbose_name=_('News slug'), editable=True,) playlist = models.IntegerField(_('playlist')) is_publish = models.BooleanField(default=False, verbose_name=_('Publish status')) author = models.CharField(max_length=255, blank=True, null=True, default=None,verbose_name=_('Author')) is_highlighted = models.BooleanField(default=False, verbose_name=_('Is highlighted')) # TODO: metadata_keys - описание ключей для динамического построения полей метаданных # TODO: metadata_values - Описание значений для динамических полей из MetadataKeys address = models.ForeignKey('location.Address', blank=True, null=True, default=None, verbose_name=_('address'), on_delete=models.SET_NULL) country = models.ForeignKey('location.Country', blank=True, null=True, on_delete=models.SET_NULL, verbose_name=_('country')) tags = generic.GenericRelation(to='main.MetaDataContent') gallery = models.ManyToManyField('gallery.Image', through='news.NewsGallery') objects = NewsQuerySet.as_manager() class Meta: """Meta class.""" verbose_name = _('news') verbose_name_plural = _('news') def __str__(self): return f'news: {self.slug}' @property def web_url(self): return reverse('web:news:rud', kwargs={'slug': self.slug}) class NewsGalleryQuerySet(models.QuerySet): """QuerySet for model News""" def originals(self): """Return QuerySet with original images.""" return self.filter(gallery__parent__isnull=True) def crops(self): """Return QuerySet with cropped images.""" return self.filter(gallery__parent__isnull=False) class NewsGallery(models.Model): news = models.ForeignKey(News, null=True, related_name='news_gallery', on_delete=models.SET_NULL, verbose_name=_('news')) image = models.ForeignKey('gallery.Image', null=True, related_name='news_gallery', on_delete=models.SET_NULL, verbose_name=_('gallery')) objects = NewsGalleryQuerySet.as_manager() class Meta: """NewsGallery meta class.""" verbose_name = _('news gallery') verbose_name_plural = _('news galleries')