1

modelcluster ParentalKey を介して、現在表示されているページが関連ページとしてリストされているサイト内のすべてのページへのリンクを取得する方法を理解しようとしています。

基本的なセットアップは次のとおりです。

# RelatedLink inherits from LinkFields, 
# both directly copied from the wagtaildemo project

class ParentPageRelatedLink(Orderable, RelatedLink):
    page = ParentalKey('ParentPage', related_name='related_links')


class ParentPage(Page):
    parent_page_types = ['ParentPage']
    subpage_types = ['ParentPage', 'ChildPage']

    def child_pages(self):
        children = ChildPage.objects.live().descendant_of(self)
        return children

ParentPage.content_panels = [
    FieldPanel('title', classname="full title"),
    FieldPanel('body', classname="full"),
    InlinePanel(ParentPage, 'related_links', label="Related links"),
]


class ChildPage(Page):
    parent_page_types = ['ParentPage']
    parent_page_types = ['ChildPage']

    def parent_index(self):
        return self.get_ancestors().type(ParentPage).last()

ChildPage.content_panels = [
    FieldPanel('title', classname="full title"),
    FieldPanel('body', classname="full"),
    InlinePanel(ChildPage, 'related_links', label="Related links"),
]

物事を正しく理解していれば、現在の ChildPage を related_links に持つ各 ParentPage を取得するには、ChildPage.parent_page_types にリストされているすべてのページを調べて、現在の ChildPage が ParentPage.related_links にあるかどうかをテストしてから、私が調べたものをすべて出力する必要があります。それらの ParentPages のそれぞれから必要です。

parent_page_types にリストされているページ タイプのインスタンスが多数ある場合、データベースへのクエリが多くなるようです。

より良い方法はありますか?

たとえば、modelcluster は、ParentPageRelatedLink で作成された ParentalKey を介して、あらゆる種類の後方参照 (db.relashionship(backref="something") を使用するときに Flask-SQLAlchemy が提供するものなど) を有効にしますか? データベーステーブルを調べると、そうは見えません。

編集

LinkFields からの related_name はこれを行う方法のようですが、LinkFields はさまざまな ParentPage のようなクラスによって継承されているため、「related_from」のようなものに設定することはできません。 ParentPage ごとに独自の ForeignKey(related_name="something") 定義を持つ個々の LinkField クラス... または、django docs の指示に従ってください。しかし、最初にループについて考えたほうがいいのでしょうか?

class LinkFields(models.Model):
    link_external = models.URLField("External link", blank=True)
    link_page = models.ForeignKey(
        'wagtailcore.Page',
        null=True,
        blank=True,
        related_name='+'
    )
    link_document = models.ForeignKey(
        'wagtaildocs.Document',
        null=True,
        blank=True,
        related_name='+'
    )

    @property
    def link(self):
        if self.link_page:
            return self.link_page.url
        elif self.link_document:
            return self.link_document.url
        else:
            return self.link_external

    panels = [
        FieldPanel('link_external'),
        PageChooserPanel('link_page'),
        DocumentChooserPanel('link_document'),
    ]

    class Meta:
        abstract = True
4

2 に答える 2