7

我正在创建一个带有 wagtail 的页面,我需要知道当前页面的上一个和下一个兄弟:

在我的纵向页面模型中,我尝试定义两种方法来查找正确的 url,但我错过了一个关键部分。要获得第一个兄弟姐妹,我可以执行以下操作:

class PortraitPage(Page):

    ...

    def first_portrait(self):
        return self.get_siblings().live().first().url

first()andlast()方法,但似乎没有next()orprevious()方法来获取直接邻居(按照它们在 wagtail 管理员中的排列顺序)。

有什么办法可以做到这一点?

4

5 回答 5

10

Django-Treebeard提供get_next_sibling并将get_prev_sibling返回树中的直接兄弟姐妹,但这些不一定是您下一个发布的兄弟姐妹。要请求那些你可以使用:

prev = page.get_prev_siblings().live().first()
next = page.get_next_siblings().live().first()

这显然也可以与任何其他查询集操作链接。

于 2016-06-22T05:41:24.430 回答
5

通过调试器一段时间后,我发现 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
于 2015-05-20T10:01:11.633 回答
1

这是处理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
于 2016-07-06T10:24:57.503 回答
0

您可以在类中定义继承自的属性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()

同级的兄弟姐妹

如果您想要 的兄弟姐妹,请在方法中PortraitPage指定如下:self.__class__type

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 }}
于 2019-03-31T03:17:30.057 回答
0

如果您想基于仅在子类中找到的属性进行任何过滤,self.get_siblings() 将失败,因为 PageQuerySet 结果是 Page 类型。

对我来说,我有一个可以按类别或标签过滤的博客索引页面。沼泽详情页面的末尾有下一篇和上一篇博文的卡片。我希望那些上一个/下一个帖子根据我登陆该页面的过滤器。

为了解决这个问题,您需要查询属于子类的对象(例如 BlogDetailPage),过滤这些对象,然后使用class.objects.sibling_of(self)获取上一篇/下一篇文章:

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)它是在一个带有子类博客页面的超类中。

于 2021-07-13T16:55:06.063 回答