I'm trying to understand how to get links to all pages in my site that have the currently viewed page listed as a related page via the modelcluster ParentalKey.
我正在尝试了解如何获取我网站中所有页面的链接,这些页面通过modelcluster ParentalKey将当前查看的页面列为相关页面。
The basic setup is as follows:
基本设置如下:
# 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"),
]
If understand things correctly, to get each ParentPage that has the current ChildPage in its related_links, I'd have to go through every page listed in ChildPage.parent_page_types, test if the current ChildPage is in the ParentPage.related_links, and then output whatever I need from each of those ParentPages.
如果理解正确,要获取其related_links中当前ChildPage的每个ParentPage,我必须遍历ChildPage.parent_page_types中列出的每个页面,测试当前的ChildPage是否在ParentPage.related_links中,然后输出任何我需要每个父页面。
Seems like it would be a lot of queries to the db if there are many instances of the page types listed in parent_page_types.
看起来如果在parent_page_types中列出了很多页面类型的实例,那么对db会有很多查询。
Is there a better way?
有没有更好的办法?
For example, does modelcluster enable any sort of backreferencing (like what Flask-SQLAlchemy provides when using db.relashionship(backref="something")) through the ParentalKey that is created in ParentPageRelatedLink? It doesn't look like it from inspecting the database tables.
例如,modelcluster是否可以通过ParentPageRelatedLink中创建的ParentalKey启用任何类型的反向引用(比如Flask-SQLAlchemy在使用db.relashionship(backref =“something”)时提供的内容)?检查数据库表看起来不像。
Edit
Ok so it seems like the related_name from the LinkFields might be a way to do this, but since I can't set it to something like "related_from" since LinkFields is inherited by many different ParentPage-like classes, it seems I have to have individual LinkField classes with their own unique ForeignKey(related_name="something") definitions for each ParentPage... Or do as instructed in the django docs. But then I might be better of with my initial thought of a loop?
好吧,看起来LinkFields中的related_name可能是一种方法,但由于我无法将其设置为类似“related_from”,因为LinkFields是由许多不同的类似ParentPage的类继承的,所以我似乎必须拥有各个LinkField类,每个ParentPage都有自己独特的ForeignKey(related_name =“something”)定义...或者按照django文档中的说明进行操作。但是我最初想到循环可能会更好吗?
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
2 个解决方案
#1
You should be able to define a @property
within the ParentPage
class. Something like:
您应该能够在ParentPage类中定义@property。就像是:
class ParentPage(Page):
...
@property
def related_pages(self):
pages = ParentPageRelatedLink.objects.filter(page_id=self.id)
return pages
#2
Try this:
parent_pages = ParentPage.objects.filter(related_links__linked_page=child_page)
"related_links" is taken from the related_name attribute of the ParentalKey on the model that you want to query. "linked_page" is a field on the ParentPageRelatedLink model that you want to filter on.
“related_links”取自您要查询的模型上ParentalKey的related_name属性。 “linked_page”是您要筛选的ParentPageRelatedLink模型上的字段。
https://docs.djangoproject.com/en/1.8/topics/db/queries/#lookups-that-span-relationships
parent_page_types is unrelated to querying pages. It's used to add a constraint to what page types a particular page type can be created under (so you can say a blog entry can only ever be created in a blog for example). It's unrelated to how pages are queried
parent_page_types与查询页面无关。它用于为可以在其下创建特定页面类型的页面类型添加约束(因此您可以说博客条目只能在博客中创建)。它与查询页面的方式无关
#1
You should be able to define a @property
within the ParentPage
class. Something like:
您应该能够在ParentPage类中定义@property。就像是:
class ParentPage(Page):
...
@property
def related_pages(self):
pages = ParentPageRelatedLink.objects.filter(page_id=self.id)
return pages
#2
Try this:
parent_pages = ParentPage.objects.filter(related_links__linked_page=child_page)
"related_links" is taken from the related_name attribute of the ParentalKey on the model that you want to query. "linked_page" is a field on the ParentPageRelatedLink model that you want to filter on.
“related_links”取自您要查询的模型上ParentalKey的related_name属性。 “linked_page”是您要筛选的ParentPageRelatedLink模型上的字段。
https://docs.djangoproject.com/en/1.8/topics/db/queries/#lookups-that-span-relationships
parent_page_types is unrelated to querying pages. It's used to add a constraint to what page types a particular page type can be created under (so you can say a blog entry can only ever be created in a blog for example). It's unrelated to how pages are queried
parent_page_types与查询页面无关。它用于为可以在其下创建特定页面类型的页面类型添加约束(因此您可以说博客条目只能在博客中创建)。它与查询页面的方式无关