[Django]-Django Wagtail Page.objects.descendant_of(inclusive=False) Error

5đź‘Ť

âś…

Firstly, this line of code is in the wrong place – putting it immediately within class HomePage(Page): means that your query will be run once at server startup, and the results will become part of the definition of HomePage. You probably want to make it a method of HomePage instead, so that you can re-run the query on every page load:

class HomePage(Page):
    body = RichTextField(blank=True)

    def special_events(self):
        return EventIndexPage.objects.descendant_of...

Now let’s look at what descendant_of is doing. EventIndexPage.objects.descendant_of(other_page) means “find all of the EventIndexPage pages which are descendants (i.e. immediate children, or grandchildren, and so on) of other_page“. Since you’re actually looking for EventPage pages, not EventIndexPage, you should use EventPage.objects.descendant_of.

Now, we need to supply other_page – i.e. tell it which page they need to be descendants of. You might try EventPage.objects.descendant_of(EventIndexPage), but this won’t work because EventIndexPage is a page type – there could potentially be several EventIndexPages on your site, and descendant_of needs to be given one specific page instance. If you’re sure you’re only ever going to have one EventIndexPage on your site, you can use EventIndexPage.objects.first() to tell it “use the first EventIndexPage that you encounter”, which makes the final function:

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)

You can safely disregard the inclusive option here: that just determines whether a page is considered to be a descendant of itself, i.e. whether the results of descendant_of(other_page) can include other_page. In this case, the EventPage.objects.descendant_of(event_index_page) results will never include event_index_page, because event_index_page is not an EventPage.

One last suggestion, though: do you actually need to deal with the EventIndexPage at all? Presumably you’re not planning to have EventPages that exist outside of the EventIndexPage, in which case it doesn’t matter whether your query says “give me all EventPages that are descendants of EventIndexPage” or “give me all EventPages regardless of where they exist”. If so, the function can become simply:

class HomePage(Page):
    body = RichTextField(blank=True)

    def special_events(self):
        return EventPage.objects.all()

Or, if you’re applying this condition because you intend to have multiple sub-sites each with their own EventPageIndex and set of events, and only want to return events for the current sub-site, you could take advantage of the fact that the events in question are also descendants of the current homepage (i.e. self) as well as being descendants of the EventPageIndex:

class HomePage(Page):
    body = RichTextField(blank=True)

    def special_events(self):
        return EventPage.objects.descendant_of(self)
👤gasman

Leave a comment