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

如果理解正确,要获取在其related_links 中具有当前 ChildPage 的每个 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”之类的东西,看来我必须有各个 LinkField 类对每个 ParentPage 都有自己独特的 ForeignKey(related_name="something") 定义...或者按照 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

2

尝试这个:

parent_pages = ParentPage.objects.filter(related_links__linked_page=child_page)

“related_links”取自您要查询的模型上 ParentalKey 的 related_name 属性。“linked_pa​​ge”是 ParentPageRelatedLink 模型上要过滤的字段。

https://docs.djangoproject.com/en/1.8/topics/db/queries/#lookups-that-span-relationships

parent_page_types 与查询页面无关。它用于对可以在哪些页面类型下创建特定页面类型添加约束(例如,您可以说博客条目只能在博客中创建)。它与如何查询页面无关

于 2015-05-15T09:15:41.267 回答
1

您应该能够@propertyParentPage类中定义 a 。就像是:

class ParentPage(Page):
    ...
    @property
    def related_pages(self):
        pages = ParentPageRelatedLink.objects.filter(page_id=self.id)
        return pages
于 2015-05-14T09:11:05.220 回答