如何扩展 Wagtail 搜索以包括子 InlinePanel Orderables?

How to extend Wagtail search to include child InlinePanel Orderables?

我有一个 Wagtail 网站,其中有一个音乐指挥页面。每个指挥都有一个部分,上面有他们的名字、照片和传记。导体详细信息存储在父页面使用 InlinePanel.

显示的子 Orderable 实例中

当用户搜索我的网站时,我希望结果包含来自指挥详细信息内部的文本(即基于 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。但这似乎是一个笨拙的解决方案。

在最新版本的 Wagtail 中推荐的实现方法是什么?

谢谢 gasman - 你的评论是我一直在寻找的解决方案。

对于任何试图实现这一点的人来说,Wagtail 有一种非常优雅的方式来定义子实体的搜索字段:RelatedFields

使用 RelatedFields 父级 页面上添加了搜索字段。有关对我有用的示例,请参见下面的代码。现在,当用户运行搜索时,结果会在指挥的传记 and/or 姓名中包含文本。

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"),
    ]