# Kod źródłowy modułu articles.models

    from articles.constants import ArticleType
    from django.db import models
    from django.db.models import QuerySet
    from django.template.defaultfilters import slugify
    from django.utils.translation import gettext as _
    from django_extensions.db.models import TimeStampedModel
    from embed_video.fields import EmbedVideoField
    from tasks.constants import IntroPopupType
    from utils.general import normalize_polish_chars

    class ArticleQuerySet(QuerySet):
        def active(self):
            return self.filter(is_active=True)

        def random_from_category(self, article, max_quant):
            return self.filter(category=article.category).exclude(id=article.id).order_by('?')[:max_quant]

    class Article(TimeStampedModel):
        title = models.CharField(max_length=70, verbose_name=_('tytuł'))
        category = models.ForeignKey('ArticleCategory', verbose_name=_('kategoria'))
        is_active = models.BooleanField(default=True, verbose_name=_('czy aktywny?'))
        short_text = models.TextField(blank=True, verbose_name=_('tekst na widoku listy'))
        long_text = models.TextField(blank=True, verbose_name=_('tekst'))
        image = models.ImageField(null=True, blank=True, upload_to='article_images/', verbose_name=_('grafika'))
        image_list = models.ImageField(null=True, blank=True, upload_to='article_images/',
                                       verbose_name=_('grafika na widoku listy'))
        author = models.CharField(blank=True, max_length=70, verbose_name=_('autor'))
        system_id = ArticleType.as_field(blank=True, null=True, verbose_name=_('typ specjalny'))
        position = models.PositiveIntegerField(default=0, blank=True, verbose_name=_('pozycja'))

        objects = ArticleQuerySet.as_manager()

        class Meta:
            ordering = ('position',)
            verbose_name = _('artykuł')
            verbose_name_plural = _('artykuły')

        def slug(self):
            return slugify(normalize_polish_chars(self.title))

        def next(self):
            return Article.objects.active().filter(position__gt=self.position).order_by('position').first()

        def previous(self):
            return Article.objects.active().filter(position__lt=self.position).order_by('-position').first()

        def __str__(self):
            return '{}'.format(self.title, )

    class ArticleCategory(models.Model):
        name = models.CharField(max_length=70, verbose_name=_('nazwa'))

        class Meta:
            verbose_name = _('kategoria artykułu')
            verbose_name_plural = _('kategorie artykułu')

        def __str__(self):
            return '{}'.format(self.name,)

    class StaticVideo(models.Model):
        system_id = IntroPopupType.as_field(verbose_name=_('id systemowe'))
        text = models.CharField(blank=True, max_length=256, verbose_name=_('tekst'))
        yt_video = EmbedVideoField(blank=True, verbose_name=_('link youtube'))

        class Meta:
            verbose_name = _('statyczne video')
            verbose_name_plural = _('statyczne video')

        def __str__(self):
            return '{}'.format(IntroPopupType.name(self.system_id), )