鹡鸰:获取上一个或下一个兄弟姐妹
Wagtail: Get previous or next sibling
我正在用 wagtail 创建一个页面,我需要知道当前页面的上一个和下一个同级:
在我的肖像页面模型中,我试图定义两种方法来找到正确的 url,但我遗漏了一个关键部分。要获得第一个兄弟姐妹,我可以执行以下操作:
class PortraitPage(Page):
...
def first_portrait(self):
return self.get_siblings().live().first().url
有first()
和last()
方法,但似乎没有next()
或previous()
方法来获取直接邻居(在令它们在 wagtail admin 中排列。
有什么办法可以实现吗?
调试了一段时间后,我发现wagtail已经有两个方法:get_prev_sibling()
和get_next_sibling()
。
所以这些方法可能看起来像这样(占前一个方法的第一页和下一个方法的最后一项):
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
Django-Treebeard 提供 get_next_sibling
和 get_prev_sibling
,它们将 return 您在树中的直接兄弟姐妹,但这些不一定是您的下一个 发布兄妹。要请求那些你可以使用:
prev = page.get_prev_siblings().live().first()
next = page.get_next_siblings().live().first()
这显然也可以与任何其他查询集操作链接。
这是处理 non-published
兄弟姐妹的版本。
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
您可以在 class 中定义继承自 Page
的属性
兄弟姐妹
如果你想要 Page
实例的兄弟姐妹,你可以使用以下内容(基于 Danielle Madeley 的回答):
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()
相同的兄弟姐妹 class
如果你想要PortraitPage
的兄弟姐妹,在type
方法中指定self.__class__
如下:
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()
模板
如果要在模板中使用它们,在定义属性后,执行以下操作:
{# This is a template #}
Previous Sibling: {{ page.next_sibling }}
Next Sibling: {{ page.prev_sibling }}
self.get_siblings() 如果您想根据仅在子 class 中找到的属性进行任何过滤,则会失败,因为 PageQuerySet 结果的类型为 Page.
对我来说,我有一个可以按类别或标签过滤的博客索引页面。
沼泽详细信息页面末尾有下一个和上一个博客 post 的卡片。
我希望那些 prev/next post 符合我登陆该页面的过滤器。
为了解决这个问题,您需要查询属于子 class 的对象(例如 BlogDetailPage),过滤这些对象,然后使用 [=20] 获取 prev/next post =]class.objects.sibling_of(自己):
def get_context(self, request, *args, **kwargs):
context = super().get_context(request, *args, **kwargs)
siblings = self.__class__.objects.sibling_of(self).live()
category_filter = request.GET.get("category", None)
tag_filter = request.GET.get("tag", None)
if category_filter:
siblings = siblings.filter(categories__slug__in=category_filter.split(","))
context["filter"] = '?category=' + category_filter
elif tag_filter:
siblings = siblings.filter(tags__slug__in=tag_filter.split(','))
context["filter"] = '?tag=' + tag_filter
else:
context["filter"] = ''
context["next_post"] = siblings.filter(path__gt=self.path).first()
context["previous_post"] = siblings.filter(path__lt=self.path).first()
return context
我使用了 self.__class__.objects.sibling_of(self)
,因为这是一个超级 class 和子 classed 博客页面。
我正在用 wagtail 创建一个页面,我需要知道当前页面的上一个和下一个同级:
在我的肖像页面模型中,我试图定义两种方法来找到正确的 url,但我遗漏了一个关键部分。要获得第一个兄弟姐妹,我可以执行以下操作:
class PortraitPage(Page):
...
def first_portrait(self):
return self.get_siblings().live().first().url
有first()
和last()
方法,但似乎没有next()
或previous()
方法来获取直接邻居(在令它们在 wagtail admin 中排列。
有什么办法可以实现吗?
调试了一段时间后,我发现wagtail已经有两个方法:get_prev_sibling()
和get_next_sibling()
。
所以这些方法可能看起来像这样(占前一个方法的第一页和下一个方法的最后一项):
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
Django-Treebeard 提供 get_next_sibling
和 get_prev_sibling
,它们将 return 您在树中的直接兄弟姐妹,但这些不一定是您的下一个 发布兄妹。要请求那些你可以使用:
prev = page.get_prev_siblings().live().first()
next = page.get_next_siblings().live().first()
这显然也可以与任何其他查询集操作链接。
这是处理 non-published
兄弟姐妹的版本。
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
您可以在 class 中定义继承自 Page
兄弟姐妹
如果你想要 Page
实例的兄弟姐妹,你可以使用以下内容(基于 Danielle Madeley 的回答):
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()
相同的兄弟姐妹 class
如果你想要PortraitPage
的兄弟姐妹,在type
方法中指定self.__class__
如下:
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()
模板
如果要在模板中使用它们,在定义属性后,执行以下操作:
{# This is a template #}
Previous Sibling: {{ page.next_sibling }}
Next Sibling: {{ page.prev_sibling }}
self.get_siblings() 如果您想根据仅在子 class 中找到的属性进行任何过滤,则会失败,因为 PageQuerySet 结果的类型为 Page.
对我来说,我有一个可以按类别或标签过滤的博客索引页面。 沼泽详细信息页面末尾有下一个和上一个博客 post 的卡片。 我希望那些 prev/next post 符合我登陆该页面的过滤器。
为了解决这个问题,您需要查询属于子 class 的对象(例如 BlogDetailPage),过滤这些对象,然后使用 [=20] 获取 prev/next post =]class.objects.sibling_of(自己):
def get_context(self, request, *args, **kwargs):
context = super().get_context(request, *args, **kwargs)
siblings = self.__class__.objects.sibling_of(self).live()
category_filter = request.GET.get("category", None)
tag_filter = request.GET.get("tag", None)
if category_filter:
siblings = siblings.filter(categories__slug__in=category_filter.split(","))
context["filter"] = '?category=' + category_filter
elif tag_filter:
siblings = siblings.filter(tags__slug__in=tag_filter.split(','))
context["filter"] = '?tag=' + tag_filter
else:
context["filter"] = ''
context["next_post"] = siblings.filter(path__gt=self.path).first()
context["previous_post"] = siblings.filter(path__lt=self.path).first()
return context
我使用了 self.__class__.objects.sibling_of(self)
,因为这是一个超级 class 和子 classed 博客页面。