问题
I'm creating a page with wagtail where I need to know the previous and next sibling of the current page:
In my portrait page model, I tried to define two methods to find the correct urls, but I'm missing a crucial part. To get the first sibling, I can just do the following:
class PortraitPage(Page):
...
def first_portrait(self):
return self.get_siblings().live().first().url
There is the first() and last() method, but there doesn't seem to be a next() or previous() method to get the direct neighbours (in the order that they are arranged in the wagtail admin).
Is there any way to achieve this?
回答1:
Django-Treebeard provides get_next_sibling and get_prev_sibling which will return your direct siblings in the tree, but these are not necessarily your next published sibling. To request those you can use:
prev = page.get_prev_siblings().live().first()
next = page.get_next_siblings().live().first()
Which can obviously also be chained with any other queryset operations.
回答2:
After going through the debugger for a while, I found out that wagtail already has two methods: get_prev_sibling() and get_next_sibling().
So the methods could look like this (accounting for the first page in the previous method and the last item in the next method):
def prev_portrait(self):
if self.get_prev_sibling():
return self.get_prev_sibling().url
else:
return self.get_siblings().last().url
def next_portrait(self):
if self.get_next_sibling():
return self.get_next_sibling().url
else:
return self.get_siblings().first().url
回答3:
Here's a version handling non-published siblings.
def next_portrait(self):
next_sibling = self.get_next_sibling()
if next_sibling and next_sibling.live:
return next_sibling.url
else:
next_published_siblings = self.get_next_siblings(
inclusive=False
).live()
if len(next_published_siblings):
return next_published_siblings[0].url
return self.get_siblings().live().first().url
def prev_portrait(self):
previous_sibling = self.get_prev_sibling()
if previous_sibling and previous_sibling.live:
return previous_sibling.url
else:
previous_published_siblings = self.get_prev_siblings(
inclusive=False
).live()
if len(previous_published_siblings):
return previous_published_siblings[0].url
return self.get_siblings().live().last().url
回答4:
You can define properties in your class that inherits from Page
Siblings
If you want the siblings of an instance of Page, you can use the following (based on Danielle Madeley's answer):
class PortraitPage(Page):
# ...
@property
def next_sibling(self):
return self.get_next_siblings().live().first()
@property
def prev_sibling(self):
return self.get_prev_siblings().live().first()
Siblings of the same class
If you want the the siblings of PortraitPage, specify self.__class__ in the type method as follows:
class PortraitPage(Page):
# ...
@property
def next_sibling(self):
return self.get_next_siblings().type(self.__class__).live().first()
@property
def prev_sibling(self):
return self.get_prev_siblings().type(self.__class__).live().first()
Template
If you want to use them in a template, after defining the properties, do the following:
{# This is a template #}
Previous Sibling: {{ page.next_sibling }}
Next Sibling: {{ page.prev_sibling }}
来源:https://stackoverflow.com/questions/30345266/wagtail-get-previous-or-next-sibling