W to:得到上一个或下一个兄弟姐妹

时间:2015-05-20 09:13:12

标签: python django wagtail

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

在我的肖像页面模型中,我试图定义两种方法来找到正确的网址,但我错过了一个关键部分。为了得到第一个兄弟姐妹,我可以做以下事情:

class PortraitPage(Page):

    ...

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

first()last()方法,但似乎不是next()previous()方法来获取直接邻居(在命令他们安排在wagtail admin)。

有没有办法实现这个目标?

5 个答案:

答案 0 :(得分:7)

Django-Treebeard提供了get_next_siblingget_prev_sibling,它们会在树中返回您的直接兄弟姐妹,但这些不一定是您下一个发布的兄弟姐妹。要请求您可以使用的那些:

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

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

答案 1 :(得分:1)

经过调试器一段时间后,我发现wagtail已经有两种方法:prerollAtRate:completionHandlerget_prev_sibling()

所以这些方法看起来像这样(占前一种方法的第一页和下一种方法的最后一项):

get_next_sibling()

答案 2 :(得分: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

答案 3 :(得分: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 }}

答案 4 :(得分: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),因为它位于具有子类博客页面的超类中。