Wagtail如何查询子页面的关联名称(内联模型)?
问题原因
Wagtail的get_children()方法默认返回的是基础Page类的查询集,即使你用type(TimelinePage)过滤了页面类型,拿到的实例仍然是核心Page类对象,只能读取Page表内置的公共字段(比如title),无法访问你在TimelinePage自定义类中定义的关联字段timeline_entries,所以会抛出AttributeError。
解决方法
调用Wagtail提供的specific()方法/specific属性,将基础Page实例转换为你自定义的TimelinePage子类实例即可,有两种写法可选:
写法1:对整个查询集调用specific()
直接在获取子页面的查询链上加specific(),返回的所有结果都会是对应自定义子类的实例:
def get_context(self, request, *args, **kwargs): context = super().get_context(request) # 新增specific()调用,将查询结果转换为TimelinePage实例 timeline_pages = self.get_children().type(TimelinePage).specific() timeline_page = timeline_pages[0] # 此时输出会是TimelinePage print(type(timeline_page).__name__) context['timeline_page'] = timeline_page # 可以正常访问timeline_entries字段 context['timeline_entries'] = timeline_page.timeline_entries.all() return context
写法2:对单个实例调用specific属性
如果你只需要转换单个页面实例,也可以单独对实例取specific属性:
def get_context(self, request, *args, **kwargs): context = super().get_context(request) timeline_pages = self.get_children().type(TimelinePage) # 对单个实例取specific属性转换为子类实例 timeline_page = timeline_pages[0].specific context['timeline_page'] = timeline_page context['timeline_entries'] = timeline_page.timeline_entries.all() return context
原理说明
Wagtail的页面数据采用分表存储:所有页面的公共字段(标题、路径、创建时间等)存在核心wagtailcore_page表,自定义页面类的额外字段、关联字段存在各自单独的数据库表。默认get_children()只查询核心表,返回的是基础Page类实例;调用specific()后Wagtail会自动关联查询自定义类对应表的数据,返回你定义的子类实例,就可以正常访问自定义的字段和关联关系了。
你当前场景下TimelinePage的max_count_per_parent配置为1,specific()不会产生额外的性能开销,可以放心使用。
内容的提问来源于stack exchange,提问作者user3170530
相关产品推荐
相关产品推荐

