Wagtail:如何查询 child 页面的相关名称(内联模型)?
Wagtail : How do I query related names (inline models) of a child page?
我有两个页面:
文章页面和时间线页面。
TimelinePage 有一个与模型 TimelinePageEntry 相关的内联面板。
TimelinePage 显示所有 child TimelinePageEntry(s) 就好了。但是,当我尝试从 ArticlePage 获取所有 TimelinePageEntry(s) 时,它失败并出现异常。
当我尝试执行以下操作时,ArticlePage 失败并出现异常:
context['timeline_entries'] = timeline_page.timeline_entries.all()
这是models.py中三个类的源代码:
import datetime
from django.db import models
from modelcluster.fields import ParentalKey
from wagtail.admin.edit_handlers import FieldPanel, InlinePanel
from wagtail.core.fields import RichTextField
from wagtail.core.models import Orderable
from wagtail.core.models import Page
class ArticlePage(Page):
date = models.DateField("Creation date", default=datetime.date.today)
hero_biography = RichTextField(blank=True)
content_panels = Page.content_panels + [
FieldPanel('date'),
FieldPanel('hero_biography'),
]
subpage_types = [
'articles.TimelinePage'
]
def get_context(self, request, *args, **kwargs):
context = super().get_context(request)
timeline_pages = self.get_children().type(TimelinePage)
timeline_page = timeline_pages[0]
# prints "Page"
print(type(timeline_page).__name__)
# prints the title of the timeline page, so I know I'm getting a query result
print(timeline_page.title)
context['timeline_page'] = timeline_page
# Throws an exception
context['timeline_entries'] = timeline_page.timeline_entries.all()
return context
class TimelinePage(Page):
max_count_per_parent = 1
subpage_types = []
content_panels = Page.content_panels + [
InlinePanel('timeline_entries', label="Timeline Entries")
]
parent_page_type = [
'articles.ArticlePage'
]
def get_context(self, request, *args, **kwargs):
# Prints "TimelinePage"
print(type(self).__name__)
# Prints a list of timeline entries
print(repr(self.timeline_entries.all()))
return super().get_context(request)
class TimelinePageEntry(Orderable):
page = ParentalKey(TimelinePage, on_delete=models.CASCADE, related_name='timeline_entries')
start_date = models.DateField()
end_date = models.DateField(null=True, blank=True)
line = RichTextField(max_length=90)
panels = [
FieldPanel('start_date'),
FieldPanel('end_date'),
FieldPanel('line'),
]
class Meta(Orderable.Meta):
ordering = ['-start_date']
看来我要做的事情应该很简单。 TimelinePage 是 child 的
文章页面。我可以从 ArticlePage 访问 TimelinePage(标题)的其他属性,但我对如何获取 TimelinePageEntries 感到困惑。
我得到的异常是:
context['timeline_entries'] = timeline_page.timeline_entries.all()
AttributeError: 'Page' object has no attribute 'timeline_entries'
这是由于 Page
实例(仅包含所有页面类型共有的数据,例如标题)和您的特定 TimelinePage
子实例class 之间的区别(它提供对在 class 上定义的所有方法、字段和关系的访问)。
self.get_children()
returns Page
类型的查询集;这是必要的,因为查询事先不知道结果中将包含哪些页面类型。 .type(TimelinePage)
将此过滤为仅给定类型的页面,但这仅作为现有查询集的过滤器 - 结果仍将保持为 Page
objects,缺少 timeline_entries
关系。
如果重写该行
timeline_pages = self.get_children().type(TimelinePage)
进入
timeline_pages = TimelinePage.objects.child_of(self)
然后这将确保结果作为 TimelinePage 实例返回,然后 timeline_entries
关系将按预期工作。
我有两个页面:
文章页面和时间线页面。
TimelinePage 有一个与模型 TimelinePageEntry 相关的内联面板。
TimelinePage 显示所有 child TimelinePageEntry(s) 就好了。但是,当我尝试从 ArticlePage 获取所有 TimelinePageEntry(s) 时,它失败并出现异常。
当我尝试执行以下操作时,ArticlePage 失败并出现异常:
context['timeline_entries'] = timeline_page.timeline_entries.all()
这是models.py中三个类的源代码:
import datetime
from django.db import models
from modelcluster.fields import ParentalKey
from wagtail.admin.edit_handlers import FieldPanel, InlinePanel
from wagtail.core.fields import RichTextField
from wagtail.core.models import Orderable
from wagtail.core.models import Page
class ArticlePage(Page):
date = models.DateField("Creation date", default=datetime.date.today)
hero_biography = RichTextField(blank=True)
content_panels = Page.content_panels + [
FieldPanel('date'),
FieldPanel('hero_biography'),
]
subpage_types = [
'articles.TimelinePage'
]
def get_context(self, request, *args, **kwargs):
context = super().get_context(request)
timeline_pages = self.get_children().type(TimelinePage)
timeline_page = timeline_pages[0]
# prints "Page"
print(type(timeline_page).__name__)
# prints the title of the timeline page, so I know I'm getting a query result
print(timeline_page.title)
context['timeline_page'] = timeline_page
# Throws an exception
context['timeline_entries'] = timeline_page.timeline_entries.all()
return context
class TimelinePage(Page):
max_count_per_parent = 1
subpage_types = []
content_panels = Page.content_panels + [
InlinePanel('timeline_entries', label="Timeline Entries")
]
parent_page_type = [
'articles.ArticlePage'
]
def get_context(self, request, *args, **kwargs):
# Prints "TimelinePage"
print(type(self).__name__)
# Prints a list of timeline entries
print(repr(self.timeline_entries.all()))
return super().get_context(request)
class TimelinePageEntry(Orderable):
page = ParentalKey(TimelinePage, on_delete=models.CASCADE, related_name='timeline_entries')
start_date = models.DateField()
end_date = models.DateField(null=True, blank=True)
line = RichTextField(max_length=90)
panels = [
FieldPanel('start_date'),
FieldPanel('end_date'),
FieldPanel('line'),
]
class Meta(Orderable.Meta):
ordering = ['-start_date']
看来我要做的事情应该很简单。 TimelinePage 是 child 的 文章页面。我可以从 ArticlePage 访问 TimelinePage(标题)的其他属性,但我对如何获取 TimelinePageEntries 感到困惑。
我得到的异常是:
context['timeline_entries'] = timeline_page.timeline_entries.all()
AttributeError: 'Page' object has no attribute 'timeline_entries'
这是由于 Page
实例(仅包含所有页面类型共有的数据,例如标题)和您的特定 TimelinePage
子实例class 之间的区别(它提供对在 class 上定义的所有方法、字段和关系的访问)。
self.get_children()
returns Page
类型的查询集;这是必要的,因为查询事先不知道结果中将包含哪些页面类型。 .type(TimelinePage)
将此过滤为仅给定类型的页面,但这仅作为现有查询集的过滤器 - 结果仍将保持为 Page
objects,缺少 timeline_entries
关系。
如果重写该行
timeline_pages = self.get_children().type(TimelinePage)
进入
timeline_pages = TimelinePage.objects.child_of(self)
然后这将确保结果作为 TimelinePage 实例返回,然后 timeline_entries
关系将按预期工作。