我正在使用Django 2.0和最新版本的Wagtail CMS。我是Wagtail的新手,我正在尝试查询EventIndexPage的子节点,它们是EventPage并让它们出现在我的主页上。
我想在家庭应用程序models.py中使用这行python:
special_events = EventIndexPage.objects.descendant_of(inclusive=False)
但它返回:
return getattr(self.get_queryset(), name)(*args, **kwargs)
TypeError: descendant_of() missing 1 required positional argument: 'other'
当我尝试在“inclusive = false”之前放入“EventPage”时,我得到一个类型错误,因为它的数组不是整数。
docs:http://docs.wagtail.io/en/v2.0/reference/pages/queryset_reference.html
家庭应用的Models.py:
from django.db import models
from event.models import EventIndexPage
from wagtail.core.models import Page
from wagtail.core.fields import RichTextField
from wagtail.admin.edit_handlers import FieldPanel
class HomePage(Page):
body = RichTextField(blank=True)
special_events = EventIndexPage.objects.descendant_of(inclusive=False)
content_panels = Page.content_panels + [
FieldPanel('body', classname="full"),
]
Models.py的事件应用程序
from django.db import models
from wagtail.core.models import Page
from wagtail.core.fields import RichTextField
from wagtail.admin.edit_handlers import FieldPanel
from wagtail.search import index
class EventIndexPage(Page):
intro = RichTextField(blank=True)
content_panels = Page.content_panels + [
FieldPanel('intro', classname="full")
]
class EventPage(Page):
date = models.DateField("Post date")
intro = models.CharField(max_length=250)
body = RichTextField(blank=True)
search_fields = Page.search_fields + [
index.SearchField('intro'),
index.SearchField('body'),
]
content_panels = Page.content_panels + [
FieldPanel('date'),
FieldPanel('intro'),
FieldPanel('body', classname="full"),
]
首先,这行代码位于错误的位置 - 将其直接放在class HomePage(Page):
中意味着您的查询将在服务器启动时运行一次,结果将成为HomePage
定义的一部分。您可能希望将其设为HomePage
的方法,以便您可以在每个页面加载时重新运行查询:
class HomePage(Page):
body = RichTextField(blank=True)
def special_events(self):
return EventIndexPage.objects.descendant_of...
现在让我们来看看descendant_of
正在做什么。 EventIndexPage.objects.descendant_of(other_page)
的意思是“找到所有EventIndexPage
页面,这些页面是other_page
的后代(即直系儿童或孙子女等)”。既然你实际上在寻找EventPage
页面,而不是EventIndexPage
,你应该使用EventPage.objects.descendant_of
。
现在,我们需要提供other_page
- 即告诉它需要哪个页面作为后代。您可以尝试EventPage.objects.descendant_of(EventIndexPage)
,但这不起作用,因为EventIndexPage
是一种页面类型 - 您的网站上可能有几个EventIndexPage
s,并且需要为descendant_of
提供一个特定的页面实例。如果你确定你的网站上只有一个EventIndexPage
,你可以使用EventIndexPage.objects.first()
告诉它“使用你遇到的第一个EventIndexPage
”,这使得最终的功能:
class HomePage(Page):
body = RichTextField(blank=True)
def special_events(self):
event_index_page = EventIndexPage.objects.first()
return EventPage.objects.descendant_of(event_index_page)
您可以放心地忽略inclusive
选项:这只是确定页面是否被认为是自身的后代,即descendant_of(other_page)
的结果是否可以包含other_page
。在这种情况下,EventPage.objects.descendant_of(event_index_page)
结果将永远不会包括event_index_page
,因为event_index_page
不是EventPage
。
最后一个建议是:你真的需要处理EventIndexPage
吗?据推测,你不打算在EventPage
之外存在EventIndexPage
s,在这种情况下,你的查询是否“给我所有EventPage
s作为EventIndexPage
的后代”或“给我所有的EventPage
s无论它们存在于何处都无关紧要”。如果是这样,该功能可以变得简单:
class HomePage(Page):
body = RichTextField(blank=True)
def special_events(self):
return EventPage.objects.all()
或者,如果您正在应用此条件,因为您打算拥有多个子站点,每个子站点都有自己的EventPageIndex
和一组事件,并且只想返回当前子站点的事件,您可以利用以下事实:有问题的事件也是当前主页(即self
)的后代,也是EventPageIndex
的后代:
class HomePage(Page):
body = RichTextField(blank=True)
def special_events(self):
return EventPage.objects.descendant_of(self)