Wagtail如何过滤PageChooserPanel可选页面 仅展示同故事下的StoryPage
实现思路
你的需求是过滤PageChooserPanel的可选值,仅显示当前编辑的StoryPage所属的同一个Story下的页面,可通过动态修改编辑页中选择器的查询集实现。
具体修改代码
首先修改StoryPage类,新增get_edit_handler方法即可,无需改动其他原有代码:
# 如未导入对应依赖请先添加 from wagtail.admin.widgets import PageChooser class StoryPage(Page): template = 'story/story_page.html' body = RichTextField() content_panels = [ FieldPanel('title', heading='Section Title', classname='collapsible'), FieldPanel('body', classname='collapsible'), MultiFieldPanel( [ InlinePanel('story_paths'), ], heading = 'Story Paths', classname = 'collapsible' ) ] parent_page_type =['story.Story'] subpage_types = [] # 新增以下方法 def get_edit_handler(self): edit_handler = super().get_edit_handler() # 跳过未保存的新页面,此时还没有关联父Story if not self.id: return edit_handler # 获取当前页面所属的父Story current_story = self.get_parent().specific # 过滤查询集:仅显示同个Story下的StoryPage,排除当前页面本身(可按需删去exclude规则) allowed_pages = StoryPage.objects.child_of(current_story).live().exclude(id=self.id) # 定位到Story Paths的InlinePanel,修改路由选择器的可选范围 for panel in edit_handler.children: if isinstance(panel, MultiFieldPanel) and panel.heading == 'Story Paths': inline_panel = panel.children[0] route_widget = inline_panel.form_class.base_fields['route'].widget if isinstance(route_widget, PageChooser): route_widget.queryset = allowed_pages return edit_handler def __str__(self): return '%s' % (self.title)
注意事项
- 该方法仅对已保存过的StoryPage生效:新创建的StoryPage未关联到任何Story,首次保存前会显示所有StoryPage,保存后编辑时会自动过滤。
- 可按需调整过滤规则:如果需要允许选择未发布的页面,删去
.live()即可;如果允许选择当前页面本身,删去.exclude(id=self.id)即可。 - 如果你使用的是Wagtail 3.0之前的旧版本,原来的
PageChooserPanel对应的widget类是wagtail.admin.widgets.pagemultipleselect.PageChooserWidget,修改isinstance判断的类即可。
内容的提问来源于stack exchange,提问作者ron_e_e
相关产品推荐
相关产品推荐

