"""News app models.""" from django.db import models from django.contrib.contenttypes import fields as generic 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)), state__in=[self.model.PUBLISHED_STATES], 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.""" STR_FIELD_NAME = 'title' # TEMPLATE CHOICES NEWSPAPER = 0 MAIN_PDF_ERB = 1 MAIN = 2 TEMPLATE_CHOICES = ( (NEWSPAPER, 'newspaper'), (MAIN_PDF_ERB, 'main.pdf.erb'), (MAIN, 'main'), ) # STATE CHOICES WAITING = 0 HIDDEN = 1 PUBLISHED = 2 PUBLISHED_EXCLUSIVE = 3 PUBLISHED_STATES = [PUBLISHED, PUBLISHED_EXCLUSIVE] STATE_CHOICES = ( (WAITING, _('Waiting')), (HIDDEN, _('Hidden')), (PUBLISHED, _('Published')), (PUBLISHED_EXCLUSIVE, _('Published exclusive')), ) 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, verbose_name=_('News slug')) playlist = models.IntegerField(_('playlist')) # author = models.CharField(max_length=255, blank=True, null=True, # default=None,verbose_name=_('Author')) state = models.PositiveSmallIntegerField(default=WAITING, choices=STATE_CHOICES, verbose_name=_('State')) 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 image_url = models.URLField(blank=True, null=True, default=None, verbose_name=_('Image URL path')) preview_image_url = models.URLField(blank=True, null=True, default=None, verbose_name=_('Preview image URL path')) template = models.PositiveIntegerField(choices=TEMPLATE_CHOICES, default=NEWSPAPER) 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') 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 is_publish(self): return self.state in self.PUBLISHED_STATES @property def web_url(self): return reverse('web:news:rud', kwargs={'slug': self.slug})