Как расширить поиск трясогузки, чтобы включить дочерние элементы InlinePanel Orderables?

У меня есть сайт о трясогузках со страницей музыкальных дирижеров. У каждого дирижера есть раздел с его именем, фотографией и биографией. Сведения о проводнике хранятся внутри дочерних Orderable экземпляров, которые родительская страница отображает с помощью InlinePanel.

Когда пользователи выполняют поиск на моем сайте, я хочу, чтобы результаты содержали текст, исходящий из сведений о проводнике (т. е. основанный на их имени и тексте полной биографии в Orderable).

Страница проводников

    class ConductorsPage(Page):
    max_count = 1
    template = 'home/conductors.html'

    content = RichTextField(
        null=True,
        blank=True,
    )

    search_fields = Page.search_fields + [
        index.SearchField('content'),
        index.SearchField('conductors'),
    ]

    content_panels = Page.content_panels + [
        FieldPanel('content', classname="full"),
        MultiFieldPanel(
            [
                InlinePanel("conductors", label="Conductor")
            ],
            heading="Conductors",
        ),
    ]

Кондуктор (можно заказать)

class Conductor(Orderable):
    page = ParentalKey('home.ConductorsPage', related_name='conductors')

    name = models.CharField(max_length=30)
    photograph = models.ForeignKey(
        "wagtailimages.Image",
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name="+",
    )
    biography = RichTextField(
        null=True,
        blank=True,
        features=['bold', 'italic', 'hr', 'link'],
    )

    search_fields = Page.search_fields + [
        index.SearchField('name'),
        index.SearchField('biography'),
    ]

    panels = [
        FieldPanel("name"),
        ImageChooserPanel("photograph"),
        FieldPanel("biography"),
    ]

Приведенный выше код выводит результаты на основе родительского поля content, но пропускает текст из Orderable (например, биографию). Я использую базу данных Postgres (wagtail.contrib.postgres_search.backend).

Я видел предложения создать метод в родительском элементе, который объединяет текст из дочерних полей и устанавливает для него SearchField. Но это кажется неуклюжим решением.

Каков рекомендуемый способ реализации этого в последних версиях трясогузки?


person badger712    schedule 06.12.2019    source источник
comment
Вы пробовали RelatedFields? docs.wagtail.io/en/stable/topics/ поиск/   -  person gasman    schedule 06.12.2019
comment
Спасибо газовщику - это именно то, что я искал!   -  person badger712    schedule 09.12.2019


Ответы (1)


Спасибо, газовщик - ваш комментарий был решением, которое я искал.

Для тех, кто пытается реализовать это, трясогузка предлагает очень элегантный способ определения полей поиска для дочерних объектов: RelatedFields

Поля поиска добавляются на родительскую страницу с помощью RelatedFields. См. код ниже для примера, который сработал для меня. Теперь, когда пользователь запускает поиск, результаты включают текст биографии и/или имени дирижера.

class ConductorsPage(Page):
    max_count = 1
    template = 'home/conductors.html'

    content = RichTextField(
        null=True,
        blank=True,
        features=['bold', 'italic', 'hr', 'link', 'image'],
    )

    search_fields = Page.search_fields + [
        index.SearchField('content'),
        index.RelatedFields('conductors', [
            index.SearchField('name'),
            index.SearchField('biography'),
        ]),
    ]

    content_panels = Page.content_panels + [
        FieldPanel('content', classname="full"),
        FieldPanel('search_description', classname="full"),
        MultiFieldPanel(
            [
                InlinePanel("conductors", label="Conductor")
            ],
            heading="Conductors",
        ),
    ]
class Conductor(Orderable):
    page = ParentalKey('home.ConductorsPage', related_name='conductors')

    name = models.CharField(max_length=30)
    photograph = models.ForeignKey(
        "wagtailimages.Image",
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name="+",
    )
    biography = RichTextField(
        null=True,
        blank=True,
        features=['bold', 'italic', 'hr', 'link'],
    )

    panels = [
        FieldPanel("name"),
        ImageChooserPanel("photograph"),
        FieldPanel("biography"),
    ]

person badger712    schedule 09.12.2019