使用 Wagtail CMS 使用 Python 检测 parent 和 child 页面类型
Detecting parent and child page types with Python using Wagtail CMS
我正在建立一个 Wagtail 网站。
将有一个事件索引页面,事件为 child 页。
每个活动页面也可以有 child 个页面,如果它是活动系列的一部分。
主要活动会将 child 活动显示为页面上的一系列链接。 child 事件还需要显示 parent 事件及其自己的同级事件。
在 models.py 我有一个事件 class。到目前为止,我正在检测 children,兄弟姐妹,parents 是这样的:
@property
def childpages(self):
event_children = Event.objects.live().descendant_of(self)
return event_children
@property
def parentpage(self):
event_parent = self.get_parent()
return event_parent
@property
def siblingpages(self):
event_siblings = Event.objects.live().sibling_of(self, inclusive=False)
return event_siblings
有没有办法找出 parent 页面类型是什么?如果它是事件索引,我不想在事件页面上显示它。我也不希望主要活动页面显示兄弟姐妹。
我用 not_child_of(somepage) 尝试过各种方法,但不太确定如何使用它。 'somepage' 指的是什么?一个class,一个变量?我习惯了 Javascript 并且对 Python 很陌生。
我会这样写:
@property
def parent_event(self):
parent_page = self.get_parent()
if parent_page.specific_class == Event:
return parent_page.specific # or just `return parent_page` if you don't need the extra detail from that page
else:
return None
@property
def sibling_events(self):
parent_page = self.get_parent()
if parent_page.specific_class == Event:
return Event.objects.live().sibling_of(self, inclusive=False)
else:
# this is not a child event, so don't return siblings
return Event.objects.none()
在 Python 中,检查对象是否是给定 class 实例的标准方法(即,在 Wagtail 术语中,页面是否属于特定类型)是 isinstance(parent_page, Event)
.
然而,对于 Wagtail 有一个额外的复杂性 - 当您使用 get_parent
和 get_children
之类的方法在页面树中上下遍历时,它无法提前知道哪种页面类型它会返回 - 因此,出于性能原因,它将 return 类型为 Page
的 "minimal" 对象,其中仅包含所有页面共有的 title
属性.因此,self.get_parent().title
会起作用,但 self.get_parent().start_date
不会。要将其转换为正确类型的 "real" 对象,您需要访问 属性 specific
,这将在后台执行额外的数据库请求以填充缺失的详细信息。
(请注意,当您 运行 明确要求特定类型页面的查询时,这不适用:对于 Event.objects.sibling_of(self)
这样的查询,我们知道我们会得到 Event
页,所以我们不需要对结果调用 specific
。)
所以,if isinstance(parent_page, Event):
不会工作 - 它永远是错误的,因为那时 parent_page
是一个基本的 Page
对象(不管页面是否真的是Event
或 EventIndex
).
if isinstance(parent_page.specific, Event):
会 工作,但它有点低效,因为在 parent_page
是事件索引页面的情况下,你正在开火关闭您并不真正需要的额外数据库请求。更好的替代方法是使用 parent_page.specific_class
,它会告诉您页面的具体类型,而无需触发额外的数据库请求。
我正在建立一个 Wagtail 网站。
将有一个事件索引页面,事件为 child 页。
每个活动页面也可以有 child 个页面,如果它是活动系列的一部分。
主要活动会将 child 活动显示为页面上的一系列链接。 child 事件还需要显示 parent 事件及其自己的同级事件。
在 models.py 我有一个事件 class。到目前为止,我正在检测 children,兄弟姐妹,parents 是这样的:
@property
def childpages(self):
event_children = Event.objects.live().descendant_of(self)
return event_children
@property
def parentpage(self):
event_parent = self.get_parent()
return event_parent
@property
def siblingpages(self):
event_siblings = Event.objects.live().sibling_of(self, inclusive=False)
return event_siblings
有没有办法找出 parent 页面类型是什么?如果它是事件索引,我不想在事件页面上显示它。我也不希望主要活动页面显示兄弟姐妹。
我用 not_child_of(somepage) 尝试过各种方法,但不太确定如何使用它。 'somepage' 指的是什么?一个class,一个变量?我习惯了 Javascript 并且对 Python 很陌生。
我会这样写:
@property
def parent_event(self):
parent_page = self.get_parent()
if parent_page.specific_class == Event:
return parent_page.specific # or just `return parent_page` if you don't need the extra detail from that page
else:
return None
@property
def sibling_events(self):
parent_page = self.get_parent()
if parent_page.specific_class == Event:
return Event.objects.live().sibling_of(self, inclusive=False)
else:
# this is not a child event, so don't return siblings
return Event.objects.none()
在 Python 中,检查对象是否是给定 class 实例的标准方法(即,在 Wagtail 术语中,页面是否属于特定类型)是 isinstance(parent_page, Event)
.
然而,对于 Wagtail 有一个额外的复杂性 - 当您使用 get_parent
和 get_children
之类的方法在页面树中上下遍历时,它无法提前知道哪种页面类型它会返回 - 因此,出于性能原因,它将 return 类型为 Page
的 "minimal" 对象,其中仅包含所有页面共有的 title
属性.因此,self.get_parent().title
会起作用,但 self.get_parent().start_date
不会。要将其转换为正确类型的 "real" 对象,您需要访问 属性 specific
,这将在后台执行额外的数据库请求以填充缺失的详细信息。
(请注意,当您 运行 明确要求特定类型页面的查询时,这不适用:对于 Event.objects.sibling_of(self)
这样的查询,我们知道我们会得到 Event
页,所以我们不需要对结果调用 specific
。)
所以,if isinstance(parent_page, Event):
不会工作 - 它永远是错误的,因为那时 parent_page
是一个基本的 Page
对象(不管页面是否真的是Event
或 EventIndex
).
if isinstance(parent_page.specific, Event):
会 工作,但它有点低效,因为在 parent_page
是事件索引页面的情况下,你正在开火关闭您并不真正需要的额外数据库请求。更好的替代方法是使用 parent_page.specific_class
,它会告诉您页面的具体类型,而无需触发额外的数据库请求。