这是我的写法:
@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中,检查对象是否为给定类的实例的标准方法(即Wagtail而言,页面是否为特定类型)是isinstance(parent_page,Event).
但是,使用Wagtail会带来额外的复杂性-当您使用诸如get_parent和get_children之类的方法在页面树上上下移动时,无法提前知道要返回哪种页面类型-因此,出于性能原因,它将返回Page类型的“最小”对象,该对象仅包含所有页面共有的属性(如title).因此,self.get_parent().title可以工作,但self.get_parent().start_date不能工作.要将其变成适当类型的“真实”对象,您需要访问特定于属性的属性,该属性将在后台进行额外的数据库请求以填充缺少的细节.
(请注意,当您运行明确要求特定类型页面的查询时,此方法将不适用:对于类似Event.objects.sibling_of(self)的查询,我们知道我们将获得事件页面,因此我们不会无需对结果进行具体调用.)
因此,如果isinstance(parent_page,Event):不起作用-它将始终为false,因为在这一点上parent_page是一个基本的Page对象(无论该页面实际上是Event还是EventIndex).
如果isinstance(parent_page.specific,Event):可以工作,但是效率有点低,因为在parent_page是事件索引页的情况下,您会触发一个您实际上不需要的额外数据库请求.更好的替代方法是使用parent_page.specific_class,它告诉您页面的特定类型而无需触发该额外的数据库请求.