Пример #1
0
class TagCaption(index.Indexed, ClusterableModel):
    tags = TaggableManager('Теги', through=TagCaptionTag, blank=True)
    raw_content = RichTextField('Текст')

    @property
    def content(self):
        return richtext(self.raw_content)

    paneles = [FieldPanel('tags'), FieldPanel('content')]

    def __str__(self):
        return ' / '.join(self.tags.all().values_list('name', flat=True))

    search_fields = [
        index.SearchField('tags'),
        index.RelatedFields('tags', [
            index.SearchField('slug'),
            index.FilterField('slug'),
        ]),
    ]

    api_fields = [
        APIField('tags', serializer=serializers.TagSerializer()),
        APIField('content')
    ]

    class Meta:
        verbose_name = 'Примечание'
        verbose_name_plural = 'Примечания'
Пример #2
0
class GuidelinePage(Page):
    parent_page_types = ['guidelines.GuidelinesIndexPage']
    subpage_types = []

    subtitle = RichTextField('Подзаголовок', blank=True, null=True)
    # поле для ввода текста
    raw_content = RichTextField('Содержание', blank=True)
    tags = ClusterTaggableManager(through='guidelines.GuidelinePageTag',
                                  blank=True)
    publish_date = models.DateField('Дата',
                                    blank=True,
                                    null=True,
                                    default=get_default_date)

    @property  # тут получаем текст с валидными тегами
    def text(self):
        return richtext(self.raw_content)

    @property
    def section_title(self):
        return self.get_parent().title

    @property
    def section_url(self):
        return self.get_parent().url

    @property
    def breadcrumbs(self):
        breadcrumbs = []
        for page in self.get_ancestors()[2:]:
            breadcrumbs.append({'title': page.title, 'url': page.url})

        return breadcrumbs

    @property
    def tags_slugs(self):
        return '\n'.join(self.tags.all().values_list('slug', flat=True))

    @property
    def clean_preview(self):
        h = html2text.HTML2Text()
        h.ignore_links = True
        h.ignore_emphasis = True
        h.ignore_images = True
        if self.subtitle:
            raw_text = h.handle(self.subtitle)
        else:
            raw_text = h.handle(self.raw_content)
        if len(raw_text) > 310:
            raw_text = raw_text[:310]
        space_index = raw_text.rfind(' ')
        raw_text = raw_text[:space_index] + '...'
        return raw_text.replace('\n', ' ').strip()

    content_panels = Page.content_panels + [
        MultiFieldPanel([FieldPanel("tags")], heading="Теги"),
        FieldPanel('subtitle'),
        FieldPanel('raw_content'),
        FieldPanel('publish_date'),
        MultiFieldPanel([
            InlinePanel(
                "guideline_authors", label="Author", min_num=0, max_num=4)
        ],
                        heading="Автор(ы)")
    ]

    search_fields = Page.search_fields + [
        index.RelatedFields('guideline_authors', [
            index.SearchField('full_name', partial_match=True),
            index.SearchField('alias')
        ]),
        index.SearchField('publish_date'),
        index.SearchField('text'),
        index.RelatedFields('tags', [
            index.SearchField('slug'),
            index.FilterField('slug'),
        ]),
        index.SearchField('tags_slugs', partial_match=True),
    ]

    api_fields = [
        APIField('breadcrumbs'),
        APIField('section_title'),
        APIField('section_url'),
        APIField('subtitle'),
        APIField('text'),
        APIField('tags', serializer=serializers.TagSerializer()),
        APIField('publish_date'),
        APIField('tags_slugs'),
        APIField('authors',
                 serializer=serializers.AuthorSerializer(
                     source='guideline_authors')),
        APIField('clean_preview'),
    ]

    def clean(self):
        super().clean()
        # автоматически создаем слаг
        if self.slug == 'default-blank-slug':
            if len(self.title) > 20:
                self.slug = slugify(self.title[:20])
            else:
                self.slug = slugify(self.title)
            if '--' in self.slug:
                self.slug = self.slug.replace('--', '-')
            if self.slug.endswith('-'):
                self.slug = self.slug[:-1]

    def get_sitemap_urls(self, request):
        return [{
            'location': self.full_url[:-1],
            'lastmod': self.last_published_at,
        }]

    class Meta:
        verbose_name = 'Памятка'
        verbose_name_plural = 'Памятки'
Пример #3
0
class ConsPageSerializer(serializers.ModelSerializer):
    tags = b_s.TagSerializer()

    class Meta:
        model = ConsPage
        fields = ('number', 'content', 'title', 'slug', 'tags')
Пример #4
0
class LawPage(Page):
    parent_page_types = ['legislation.LawsSectionPage']
    subpage_types = []

    full_title = models.TextField("Полное название", max_length=900, null=True)
    raw_subtitle = RichTextField(verbose_name='Подзаголовок', blank=True)
    content = RichTextField(verbose_name='Содержание', blank=True)
    note = models.CharField(verbose_name='Примечание',
                            max_length=300,
                            blank=True)
    doc = models.ForeignKey('base.CustomDocument',
                            blank=True,
                            null=True,
                            on_delete=models.SET_NULL,
                            related_name='+',
                            verbose_name="Документ")
    publish_date = models.DateField(
        "Дата обнародования",
        blank=True,
        null=True,
        help_text='Дата, с которой начинается действие документа')
    tags = ClusterTaggableManager(through='legislation.LawPageTag', blank=True)

    @property
    def subtitle(self):
        return richtext(self.raw_subtitle)

    @property
    def text(self):
        return richtext(self.content)

    @property
    def is_obsolete(self):
        if 'утрат' in self.note:
            return True
        else:
            return False

    @property
    def breadcrumbs(self):
        breadcrumbs = []
        for page in self.get_ancestors()[2:]:
            breadcrumbs.append({'title': page.title, 'url': page.url})
        return breadcrumbs

    @property
    def section_title(self):
        return self.get_parent().title

    @property
    def section_url(self):
        return self.get_parent().url

    @property
    def tags_slugs(self):
        return '\n'.join(self.tags.all().values_list('slug', flat=True))

    @property
    def clean_preview(self):
        h = html2text.HTML2Text()
        h.ignore_links = True
        h.ignore_emphasis = True
        h.ignore_images = True
        if self.subtitle:
            raw_text = h.handle(self.subtitle)
        else:
            raw_text = h.handle(self.raw_content)
        if len(raw_text) > 310:
            raw_text = raw_text[:310]
        space_index = raw_text.rfind(' ')
        raw_text = raw_text[:space_index] + '...'
        return raw_text.replace('\n', ' ').strip()

    def clean(self):
        super().clean()
        # автоматически создаем слаг и заголовок
        if len(self.full_title) >= 254:
            self.title = self.full_title[:254]
        else:
            self.title = self.full_title
        if self.slug == 'default-blank-slug':
            if self.doc:
                dot_index = self.doc.filename.rfind('.')
                filename = self.doc.filename[:dot_index]
                self.slug = slugify(filename)

            elif len(self.title) > 100:
                self.slug = slugify(self.title[:100])
            else:
                self.slug = slugify(self.title)
        if '--' in self.slug:
            self.slug = self.slug.replace('--', '-')
        if self.slug.endswith('-'):
            self.slug = self.slug[:-1]

    def get_sitemap_urls(self, request):
        return [{
            'location': self.full_url[:-1],
            'lastmod': self.last_published_at,
        }]

    content_panels = [
        FieldPanel('full_title'),
        FieldPanel('raw_subtitle'),
        FieldPanel('note'),
        FieldPanel('publish_date'),
        DocumentChooserPanel('doc'),
        FieldPanel('tags'),
        MultiFieldPanel([InlinePanel("related_docs", label='Документ')],
                        heading='Связанные документы'),
        FieldPanel('content'),
    ]

    search_fields = Page.search_fields + [
        index.SearchField('full_title'),
        index.SearchField('subtitle'),
        index.SearchField('content'),
        index.SearchField('tags'),
        index.RelatedFields('tags', [
            index.SearchField('slug'),
            index.FilterField('slug'),
            index.FilterField('name'),
            index.SearchField('name')
        ]),
        index.SearchField('tags_slugs', partial_match=True),
        index.SearchField('publish_date'),
        index.FilterField('publish_date'),
    ]

    api_fields = [
        APIField('full_title'),
        APIField('subtitle'),
        APIField('note'),
        APIField('text'),
        APIField('doc', serializer=base_serializers.DocSerializer()),
        APIField('breadcrumbs'),
        APIField('section_title'),
        APIField('section_url'),
        APIField('publish_date', serializer=base_serializers.DateSerializer()),
        APIField('tags', serializer=base_serializers.TagSerializer()),
        APIField('related_docs',
                 serializer=serializers.RelatedDocsSerializer()),
        APIField('clean_preview'),
        APIField('tags_slugs')
    ]

    class Meta:
        verbose_name = 'Законодательный акт'
        verbose_name_plural = 'Законодательные акты'
Пример #5
0
class BlogArticlePage(Page):
    """
    Запись в блоге
    """
    parent_page_types = ['blog.BlogIndexPage']
    subpage_types = []

    raw_subtitle = RichTextField(null=True, blank=True)
    content = StreamField([('full_richtext', base_blocks.RichTextBlock()),
                           ('table', TableBlock(label='Таблица')),
                           ('raw_html', RawHTMLBlock(label='HTML'))],
                          null=True,
                          blank=True,
                          help_text='Содержание')
    tags = ClusterTaggableManager(through='blog.BlogPageTag', blank=True)
    publish_date = models.DateField(blank=True, null=True)

    @property
    def subtitle(self):
        return richtext(self.raw_subtitle)

    @property
    def breadcrumbs(self):
        breadcrumbs = []
        for page in self.get_ancestors()[2:]:
            breadcrumbs.append({'title': page.title, 'url': page.url})
        return breadcrumbs

    @property
    def section_title(self):
        title = self.get_parent().title
        if 'Дискуссионные вопросы' in title:
            return 'Дискуссионные вопросы'
        else:
            return title

    @property
    def section_url(self):
        return self.get_parent().url

    @property
    def tags_slugs(self):
        return '\n'.join(self.tags.all().values_list('slug', flat=True))

    @property
    def clean_preview(self):
        h = html2text.HTML2Text()
        h.ignore_links = True
        h.ignore_emphasis = True
        h.ignore_images = True
        if self.subtitle:
            raw_text = h.handle(self.subtitle)
        else:
            raw_text = h.handle(self.content[0].value.source)
            if len(raw_text) > 310:
                raw_text = raw_text[:310]
            space_index = raw_text.rfind(' ')
            raw_text = raw_text[:space_index] + '...'
        return raw_text.replace('\n', ' ').strip()

    content_panels = Page.content_panels + [
        FieldPanel('raw_subtitle', heading='Подзаголовок'),
        StreamFieldPanel('content', heading='Содержание'),
        MultiFieldPanel([
            InlinePanel("blog_authors", label="Author", min_num=1, max_num=4)
        ],
                        heading="Автор(ы)"),
        MultiFieldPanel([FieldPanel("tags")], heading="Теги"),
        FieldPanel('publish_date')
    ]

    search_fields = Page.search_fields + [
        index.RelatedFields('blog_authors', [
            index.SearchField('full_name', partial_match=True),
            index.SearchField('alias')
        ]),
        index.SearchField('tags_slugs', partial_match=True),
        index.SearchField('subtitle'),
        index.SearchField('content'),
        index.SearchField('publish_date'),
        index.FilterField('publish_date')
    ]

    api_fields = [
        APIField('breadcrumbs'),
        APIField('section_title'),
        APIField('section_url'),
        APIField('subtitle'),
        APIField('content'),
        APIField('tags', serializer=serializers.TagSerializer()),
        APIField(
            'authors',
            serializer=serializers.AuthorSerializer(source='blog_authors')),
        APIField('publish_date', serializer=serializers.DateSerializer()),
        APIField('tags_slugs'),
        APIField('clean_preview')
    ]

    def clean(self):
        super().clean()
        # автоматически создаем слаг
        if self.slug == 'default-blank-slug':
            if len(self.title) > 30:
                self.slug = slugify(self.title[:30])
            else:
                self.slug = slugify(self.title)
            if '--' in self.slug:
                self.slug = self.slug.replace('--', '-')
            if self.slug.endswith('-'):
                self.slug = self.slug[:-1]

    def get_sitemap_urls(self, request):
        return [{
            'location': self.full_url[:-1],
            'lastmod': self.last_published_at,
        }]

    class Meta:
        verbose_name = 'Запись в блоге'
        verbose_name_plural = 'Записи в блогах'
Пример #6
0
class ConsPage(Page):
    """Страница консультации"""

    subpage_types = []
    parent_page_types = ['cons.ConsIndexPage']

    number = models.PositiveIntegerField('Номер', unique=True, default=get_default_cons_number)
    tags = ClusterTaggableManager('Теги', through=ConsPageTag, blank=True)
    publish_date = models.DateField('Дата', null=True,  default=get_default_date)
    too_old = models.BooleanField('Устарела', default=False, null=False, )  # если конса неактаульная, ставим галочку
    
    @property
    def preview_client(self):
        '''
        предпросмотр имен клиентов, задающих вопрос
        '''
        for block in self.content:
            if block.block_type == 'question':
                clients = list()
                for sub_block in block.value:
                    if sub_block.block_type == 'client':
                        clients.append(sub_block.value)

                clients_str = str()
                for client in clients:
                    clients_str += client
                    clients_str += ', '
                
                clients_str = clients_str[:-2]

                return clients_str

    @property
    def preview_question(self):
        for block in self.content:
            if block.block_type == 'question':
                for sub_block in block.value:
                    if sub_block.block_type == 'question_text':
                        html = sub_block.value.source
                        soup = BeautifulSoup(html, 'html.parser')
                        links = soup.find_all('a', href=True)
                        if links:
                            for link in links:
                                link.replace_with_children()
                            html = str(soup)

                        if len(html) > 1000:
                            text = html[:1000]
                            last_dot_index = text.rfind('. ')
                            html = text[:last_dot_index] + '...</p>'
                            return html
                        else:
                            return html

    @property
    def section_title(self):
        return self.get_parent().title

    @property
    def section_url(self):
        return self.get_parent().url

    @property
    def breadcrumbs(self):
        breadcrumbs = []
        for page in self.get_ancestors()[2:]:
            breadcrumbs.append({'title': page.title, 'url': page.url})
        return breadcrumbs

    @property
    def clean_preview(self):
        h = html2text.HTML2Text()
        h.ignore_links = True
        h.ignore_emphasis = True
        h.ignore_images = True
        raw_text = h.handle(self.preview_question)
        return raw_text.replace('\n', ' ').strip()

    authors = ParentalManyToManyField(Author, blank=True)

    content = StreamField(
        [
            ('question', QuestionBlock()),
            ('answer', AnswerBlock()),
        ], blank=True, verbose_name='Содержание')

    content_panels = [
        FieldPanel("number"),
        FieldPanel("tags"),
        StreamFieldPanel("content"),
        FieldPanel('publish_date'),
        FieldPanel('too_old'),
        MultiFieldPanel(
            [InlinePanel("previous_cons", label='Консультация')
            ], heading='Предыдущие консультации')
        ]
    
    @property
    def tags_slugs(self):
        return '\n'.join(self.tags.all().values_list('slug', flat=True))


    search_fields = Page.search_fields + [
        index.SearchField('number'),
        index.FilterField('number'),
        index.SearchField('publish_date'),
        index.FilterField('publish_date'),
        index.SearchField('preview_client'),
        index.SearchField('preview_question'),
        index.FilterField('authors'),
        index.SearchField('content'),
        index.SearchField('tags_slugs', partial_match=True),
        index.RelatedFields('tags', [
            index.SearchField('slug'),
            index.FilterField('slug'),
        ]),
        
    ]

    api_fields = [
        APIField('breadcrumbs'),
        APIField('section_title'),
        APIField('section_url'),
        APIField('number'),
        APIField('tags', serializer=serializers.TagSerializer()),
        APIField('publish_date', serializer=serializers.DateSerializer()),
        APIField('authors'),
        APIField("preview_client"),
        # APIField("preview_question"),
        APIField("content"),
        APIField('previous_cons'),
        APIField('too_old'),
        APIField('tags_slugs'),
        APIField('authors', serializer=serializers.AuthorSerializer()),
        APIField('clean_preview'),
    ]

    def clean(self):
        super().clean()
        # автоматически создаем заголовок и слаг,
        # добавляя к номеру консультации и ее теги
        title = 'Консультация №' + str(self.number) + ': '
        for tag in self.tags.names():
            title += tag
            title += ', '
        title = title[:-2]
        self.title = title
        slug = f'c-{str(self.number)}'
        self.slug = slug

    def save(self, *args, **kwargs):
        super().save()
        
        for block in self.content:
            if block.block_type == 'answer':
                # TODO удалить всех авторов на всякий случай
                for sub_block in block.value:
                    if sub_block.block_type == 'author':
                        a = Author.objects.get(id=sub_block.value.id)
                        self.authors.add(a)

        return super().save(*args, **kwargs)

    def get_sitemap_urls(self, request):
        return [{
            'location': self.full_url[:-1],
            'lastmod': self.last_published_at,
        }]

    class Meta:
        verbose_name = 'Консультация'
        verbose_name_plural = 'Консультации'
Пример #7
0
class FAQPage(Page):
    parent_page_types = ['FAQIndexPage',]
    subpage_types = []
    number = models.PositiveIntegerField(verbose_name='Номер', unique=True, default=get_default_faq_number)
    tags = ClusterTaggableManager(through=FAQPageTag, blank=True, verbose_name='Теги')
    # поле для ввода текста
    raw_content = RichTextField('Содержание', blank=True)

    content_panels = Page.content_panels + [
        FieldPanel('number'),
        FieldPanel('tags'),
        FieldPanel('raw_content'),
    ]


    @property  # тут получаем текст с валидными тегами
    def text(self):
        return richtext(self.raw_content)

    @property 
    def tag_slugs(self):
        return '\n'.join(self.tags.all().values_list('slug', flat=True))

    @property
    def section_title(self):
        return self.get_parent().title

    @property
    def section_url(self):
        return self.get_parent().url

    @property
    def breadcrumbs(self):
        breadcrumbs = []
        for page in self.get_ancestors()[2:]:
            breadcrumbs.append({'title': page.title, 'url': page.url})
        return breadcrumbs

    @property
    def clean_preview(self):
        h = html2text.HTML2Text()
        h.ignore_links = True
        h.ignore_emphasis = True
        h.ignore_images = True
        raw_text = h.handle(self.raw_content)
        if len(raw_text) > 310:
            raw_text = raw_text[:310]
        space_index = raw_text.rfind(' ')
        raw_text = raw_text[:space_index] + '...'
        return raw_text.replace('\n', ' ').strip()

    search_fields = Page.search_fields + [
        index.SearchField('number'),
        index.SearchField('text'),
        index.FilterField('tags'),
        index.SearchField('tag_slugs'),
        index.FilterField('number')
    ]

    api_fields = [
    APIField('section_title'),
    APIField('section_url'),
    APIField('breadcrumbs'),
    APIField('number'),
    APIField('tags', serializer=serializers.TagSerializer()),
    APIField('text'),
    APIField('number'),
    APIField('clean_preview'),
    ]
    
    def clean(self):
        super().clean()
        if self.slug == 'default-blank-slug':
            slug = f'f-{str(self.number)}'
            if len(self.title) > 30:
                self.slug = slug + '-' + slugify(self.title[:30])
            else:
                self.slug = slug + '-' + slugify(self.title)

    def get_sitemap_urls(self, request):
        return [{
            'location': self.full_url[:-1],
            'lastmod': self.last_published_at,
        }]
        
    class Meta:
        verbose_name = 'Частый вопрос'
Пример #8
0
class LibraryItemPage(Page):
    parent_page_types = ['library.LibraryIndexPage']
    subpage_types = []

    raw_subtitle = RichTextField(verbose_name='Подзаголовок',
                                 blank=True,
                                 null=True)
    content = StreamField([('full_richtext', base_blocks.RichTextBlock()),
                           ('table', TableBlock(label='Таблица')),
                           ('raw_html', RawHTMLBlock(label='HTML'))],
                          null=True,
                          blank=True,
                          verbose_name='Содержание')
    doc = models.ForeignKey('base.CustomDocument',
                            blank=True,
                            null=True,
                            on_delete=models.SET_NULL,
                            related_name='+',
                            verbose_name="Документ")
    publish_date = models.DateField("Дата публикации", blank=True, null=True)
    tags = ClusterTaggableManager(through='library.LibraryPageTag', blank=True)

    @property
    def subtitle(self):
        return richtext(self.raw_subtitle)

    @property
    def breadcrumbs(self):
        breadcrumbs = []
        for page in self.get_ancestors()[2:]:
            breadcrumbs.append({'title': page.title, 'url': page.url})
        return breadcrumbs

    @property
    def section_title(self):
        return self.get_parent().title

    @property
    def section_url(self):
        return self.get_parent().url

    @property
    def tags_slugs(self):
        return '\n'.join(self.tags.all().values_list('slug', flat=True))

    content_panels = Page.content_panels + [
        FieldPanel('publish_date'),
        FieldPanel('raw_subtitle'),
        StreamFieldPanel('content'),
        MultiFieldPanel([
            InlinePanel("library_authors", label="Автор", min_num=0, max_num=5)
        ],
                        heading="Автор(ы)"),
        FieldPanel('tags'),
        DocumentChooserPanel('doc'),
    ]

    search_fields = Page.search_fields + [
        index.SearchField('subtitle'),
        index.SearchField('content'),
        index.SearchField('tags'),
        index.RelatedFields('tags', [
            index.SearchField('slug'),
            index.FilterField('slug'),
            index.FilterField('name'),
            index.SearchField('name')
        ]),
        index.SearchField('tags_slugs', partial_match=True),
        index.SearchField('publish_date'),
        index.FilterField('publish_date'),
    ]

    api_fields = [
        APIField('breadcrumbs'),
        APIField('section_title'),
        APIField('section_url'),
        APIField('publish_date', serializer=serializers.DateSerializer()),
        APIField('tags', serializer=serializers.TagSerializer()),
        APIField('subtitle'),
        APIField('content'),
        APIField(
            'authors',
            serializer=serializers.AuthorSerializer(source='library_authors')),
        APIField('doc', serializer=serializers.DocSerializer()),
        APIField('tags_slugs'),
    ]

    def get_sitemap_urls(self, request):
        return [{
            'location': self.full_url[:-1],
            'lastmod': self.last_published_at,
        }]

    def clean(self):
        super().clean()
        # автоматически создаем слаг
        if self.slug == 'default-blank-slug':
            if len(self.title) > 40:
                self.slug = slugify(self.title[:40])
            else:
                self.slug = slugify(self.title)
            if '--' in self.slug:
                self.slug = self.slug.replace('--', '-')
            if self.slug.endswith('-'):
                self.slug = self.slug[:-1]

    class Meta:
        verbose_name = 'Материал библиотеки'
        verbose_name_plural = 'Материалы библиотеки'
Пример #9
0
class SamplePage(Page):
    parent_page_types = ['samples.SamplesIndexPage']
    subpage_types = []

    raw_subtitle = RichTextField('Подзаголовок', blank=True, null=True)
    tags = ClusterTaggableManager(through='samples.SamplePageTag', blank=True)
    # поле для ввода текста
    raw_content = RichTextField('Содержание', blank=True)
    doc = models.ForeignKey('base.CustomDocument',
                            blank=True,
                            null=True,
                            on_delete=models.SET_NULL,
                            related_name='+')

    @property
    def subtitle(self):
        return richtext(self.raw_subtitle)

    @property  # тут получаем текст с валидными тегами
    def text(self):
        return richtext(self.raw_content)

    @property
    def section_title(self):
        return self.get_parent().title

    @property
    def section_url(self):
        return self.get_parent().url

    @property
    def breadcrumbs(self):
        breadcrumbs = []
        for page in self.get_ancestors()[2:]:
            breadcrumbs.append({'title': page.title, 'url': page.url})
        return breadcrumbs

    @property
    def tags_slugs(self):
        return '\n'.join(self.tags.all().values_list('slug', flat=True))

    @property
    def clean_preview(self):
        h = html2text.HTML2Text()
        h.ignore_links = True
        h.ignore_emphasis = True
        h.ignore_images = True
        if self.subtitle:
            raw_text = h.handle(self.subtitle)
        else:
            raw_text = h.handle(self.raw_content)
        if len(raw_text) > 310:
            raw_text = raw_text[:310]
        space_index = raw_text.rfind(' ')
        raw_text = raw_text[:space_index] + '...'
        return raw_text.replace('\n', ' ').strip()

    def clean(self):
        super().clean()
        # автоматически создаем слаг
        if self.slug == 'default-blank-slug':
            if len(self.title) > 30:
                self.slug = slugify(self.title[:30])
            else:
                self.slug = slugify(self.title)
            if '--' in self.slug:
                self.slug = self.slug.replace('--', '-')
            if self.slug.endswith('-'):
                self.slug = self.slug[:-1]

    content_panels = Page.content_panels + [
        FieldPanel('raw_subtitle'),
        FieldPanel('raw_content', heading='Содержание'),
        DocumentChooserPanel('doc', heading='Документ'),
        MultiFieldPanel([FieldPanel("tags")], heading="Теги"),
    ]

    search_fields = Page.search_fields + [
        index.SearchField('subtitle'),
        index.SearchField('text'),
        index.RelatedFields('tags', [
            index.SearchField('slug'),
            index.FilterField('slug'),
        ]),
        index.SearchField('tags_slugs', partial_match=True),
    ]

    api_fields = [
        APIField('title'),
        APIField('breadcrumbs'),
        APIField('section_title'),
        APIField('section_url'),
        APIField('subtitle'),
        APIField('text'),
        APIField('tags', serializer=serializers.TagSerializer()),
        APIField('doc', serializer=serializers.DocSerializer()),
        APIField('tags_slugs'),
        APIField('clean_preview')
    ]

    def get_sitemap_urls(self, request):
        return [{
            'location': self.full_url[:-1],
            'lastmod': self.last_published_at,
        }]

    class Meta:
        verbose_name = 'Образец документа'
        verbose_name_plural = 'Образец документа'
Пример #10
0
class SubjectArticlePage(Page):
    parent_page_types = ['SubjectIndexPage', 'SubjectArticlePage']
    subpage_types = ['SubjectArticlePage']
    preview_image = models.ForeignKey(
    'wagtailimages.Image', on_delete=models.SET_NULL, related_name='+', null=True, blank=True
    )
    preview_desc = models.TextField(verbose_name='Описание сюжета', max_length=800, blank=True)

    raw_subtitle = RichTextField(null=True, blank=True)
    content = StreamField(
        [
            ('full_richtext', base_blocks.RichTextBlock()),
            ('table', TableBlock(label='Таблица')),
            ('raw_html', RawHTMLBlock(label='HTML')),
            ('incut', CustomPageChooserBlock(label='Врезка'))
        ], null=True, blank=True, help_text='Содержание')
    tags = ClusterTaggableManager(through='subjects.SubjectArticleTag', blank=True)
    publish_date = models.DateField(blank=True, null=True)

    news = StreamField(
        [
            ('full_richtext', base_blocks.RichTextBlock()),
        ], null=True, blank=True, help_text='Новости/материалы по теме'
    )

    @property
    def subtitle(self):
        return richtext(self.raw_subtitle)
    
    @property
    def tags_slugs(self):
        return '\n'.join(self.tags.all().values_list('slug', flat=True))

    @property
    def clean_preview(self):
        h = html2text.HTML2Text()
        h.ignore_links = True
        h.ignore_emphasis = True
        h.ignore_images = True
        if self.subtitle:
            raw_text = h.handle(self.subtitle)
        else:
            raw_text = h.handle(self.content[0].value.source)
            if len(raw_text) > 310:
                raw_text = raw_text[:310]
            space_index = raw_text.rfind(' ')
            raw_text = raw_text[:space_index] + '...'
        return raw_text.replace('\n', ' ').strip()

    @property
    def breadcrumbs(self):
        breadcrumbs = []
        for page in self.get_ancestors()[2:]:
            breadcrumbs.append({'title': page.title, 'url': page.url})
        return breadcrumbs

    @property
    def section_title(self):
        title = self.get_parent().title
        return title

    @property
    def section_url(self):
        return self.get_parent().url

    content_panels = Page.content_panels + [
        FieldPanel('raw_subtitle', heading='Подзаголовок'),
        StreamFieldPanel('content', heading='Содержание'),
        StreamFieldPanel('news', heading='Новости по теме'),
        MultiFieldPanel(
            [
                InlinePanel("subject_authors", label="Автор", min_num=1, max_num=4)
            ],
            heading="Автор(ы)"
        ),
        MultiFieldPanel(
            [
                FieldPanel("tags")
            ],
            heading="Теги"
        ),
        FieldPanel('publish_date', heading='Дата публикации'),
        ImageChooserPanel('preview_image', heading='Картинка для предпросмотра'),
        FieldPanel('preview_desc')
    ]

    api_fields = [
        APIField('subtitle'),
        APIField('content'),
        APIField('authors', serializer=serializers.AuthorSerializer(source='subject_authors')),
        APIField('tags', serializer=serializers.TagSerializer()),
        APIField('publish_date', serializer=serializers.DateSerializer()), 
        APIField('news'),
        APIField('clean_preview'),
        APIField('preview_image'),
        APIField('preview_desc'),
        APIField('breadcrumbs'),
        APIField('section_title'),
        APIField('section_url')
    ]

    search_fields = Page.search_fields + [
        index.RelatedFields('subject_authors',[
            index.SearchField('full_name', partial_match=True),
            index.SearchField('alias')]),
        index.SearchField('tags_slugs', partial_match=True),
        index.SearchField('subtitle'),
        index.SearchField('content'),
        index.SearchField('publish_date'),
        index.FilterField('publish_date'),
        index.SearchField('news')
    ]

    def clean(self):
            super().clean()
            # автоматически создаем слаг
            if self.slug == 'default-blank-slug':
                if len(self.title) > 30:
                    self.slug = slugify(self.title[:30])
                else:
                    self.slug = slugify(self.title)
                if '--' in self.slug:
                    self.slug = self.slug.replace('--','-')
                if self.slug.endswith('-'):
                    self.slug = self.slug[:-1]

    def get_sitemap_urls(self, request):
        return [{
            'location': self.full_url[:-1],
            'lastmod': self.last_published_at,
        }]  

    class Meta:
        verbose_name = 'Страница сюжета'
        verbose_name_plural = "Страницы сюжетов"
Пример #11
0
class PracticePage(Page):
    parent_page_types = ['practice.PracticeIndexPage']
    subpage_types = []
    full_title = models.TextField("Полное название", max_length=800, null=True)
    raw_subtitle = RichTextField(verbose_name='Подзаголовок', blank=True)
    content = RichTextField(verbose_name='Содержание', blank=True)
    doc = models.ForeignKey(
        'base.CustomDocument', blank=True, null=True,
         on_delete=models.SET_NULL, related_name='+',
         verbose_name= "Документ")
    publish_date = models.DateField("Дата обнародования", null=True)
    category = ForeignKey('practice.CaseCategory', blank=True, null=True, on_delete=models.SET_NULL, verbose_name="Категория дел")
    level = ForeignKey('practice.CourtLevel', blank=True, null=True, on_delete=models.SET_NULL, verbose_name="Уровень суда")
    tags = ClusterTaggableManager(through='practice.PracticePageTag', blank=True)

    @property
    def subtitle(self):
        return richtext(self.raw_subtitle)

    @property
    def text(self):
        return richtext(self.content)

    @property
    def breadcrumbs(self):
        breadcrumbs = []
        for page in self.get_ancestors()[2:]:
            breadcrumbs.append({'title': page.title, 'url': page.url})
        return breadcrumbs

    @property
    def section_title(self):
        return self.get_parent().title

    @property
    def section_url(self):
        return self.get_parent().url

    @property
    def tags_slugs(self):
        return '\n'.join(self.tags.all().values_list('slug', flat=True))
    
    def get_sitemap_urls(self, request):
        return [{
            'location': self.full_url[:-1],
            'lastmod': self.last_published_at,
        }]


    def clean(self):
        super().clean()
        # автоматически создаем слаг и заголовок
        if len(self.full_title) >= 254  :
            self.title = self.full_title[:254]
        else:
            self.title = self.full_title
        if self.slug == 'default-blank-slug':
            if self.doc:
                dot_index = self.doc.filename.rfind('.')
                filename = self.doc.filename[:dot_index]
                self.slug = slugify(filename)
            elif len(self.title) > 80:
                self.slug = slugify(self.title[:80])
            else:
                self.slug = slugify(self.title)
        if '--' in self.slug:
            self.slug = self.slug.replace('--','-')
        if self.slug.endswith('-'):
            self.slug = self.slug[:-1]

    @property
    def clean_preview(self):
        h = html2text.HTML2Text()
        h.ignore_links = True
        h.ignore_emphasis = True
        h.ignore_images = True
        if self.subtitle:
            raw_text = h.handle(self.subtitle)
        else:
            raw_text = h.handle(self.raw_content)
        if len(raw_text) > 310:
            raw_text = raw_text[:310]
        space_index = raw_text.rfind(' ')
        raw_text = raw_text[:space_index] + '...'
        return raw_text.replace('\n', ' ').strip()

    search_fields = Page.search_fields + [
    index.SearchField('full_title'),
    index.SearchField('subtitle'),
    index.SearchField('content'),
    index.SearchField('tags'),
    index.RelatedFields('tags', [
        index.SearchField('slug'),
        index.FilterField('slug'),
        index.FilterField('name'),
        index.SearchField('name')]),
    
    index.SearchField('tags_slugs', partial_match=True),
    index.SearchField('category'),
    index.FilterField('level'),
    index.FilterField('category'),
    index.RelatedFields('category', [
        index.FilterField('name'),
    ]),
]   

    api_fields = [
        APIField('full_title'),
        APIField('subtitle'),
        APIField('text'),
        APIField('doc', serializer=base_serializers.DocSerializer()),
        APIField('breadcrumbs'),
        APIField('section_title'),
        APIField('section_url'),
        APIField('publish_date', serializer=base_serializers.DateSerializer()),
        APIField('category', serializer=serializers.CategorySerializer()),
        APIField('level', serializer=serializers.LevelSerializer()),
        APIField('tags', serializer=base_serializers.TagSerializer()),
        APIField('related_docs', serializer=serializers.RelatedDocsSerializer()),
        APIField('clean_preview'),
    ]

    content_panels =  [
        FieldPanel('full_title'),
        FieldPanel('raw_subtitle'),
        FieldPanel('publish_date'),
        DocumentChooserPanel('doc'),
        FieldPanel('category', widget=forms.RadioSelect),
        FieldPanel('level', widget=forms.RadioSelect),
        FieldPanel('tags'),
        MultiFieldPanel([InlinePanel("related_docs", label='Документ')
            ], heading='Связанные документы'
            ),
        FieldPanel('content'),
        ]

    class Meta:
        verbose_name = 'Страница судебной практики'
        verbose_name_plural = 'Страницы судебной практики'