覆盖 Wagtail Page.get_url()?

Override Wagtail Page.get_url()?

为了尝试仅使用 Wagtail Page 树作为导航结构,我声明了以下内容,以便在需要时可以呈现 link 而不是页面 url:

class Node(Page):
  
    class Meta:
        verbose_name = 'Node (no content or link)'

    link = models.CharField(max_length=255, default='', blank='True', help_text='Optional.  Leave blank if serving as a parent page')

    content_panels = Page.content_panels + [
        FieldPanel('link')
    ]

    def get_url(self, **kwargs):
        if self.link != '':
            return self.link
        else:
            return super().get_url(self, **kwargs)

在模板中,我尝试了 {{ item.url }}{{ item.specific.url }},其中 item 是页面树中正在迭代的项目。由 Wagtail 的 Page.get_url() 函数定义的项目的 url 总是被渲染,而我定义的 def get_url() 永远不会被执行。

我知道 Wagtail Menus,但试图在这个项目中没有其他依赖项,所以除了上述是否是最好的架构之外,我在让它工作时还缺少什么?


为了跟进这里,我已经关注 these instructions,并且在 class Node(Page) 模型上,我现在用以下内容代替 def get_url

def get_url_parts(self, *args, **kwargs):
    site_id, root_url, page_path = super().get_url_parts(*args, **kwargs)
    # return an alternative page_path if link has a value
    if self.link.strip() != '':
        page_path = self.link

    return site_id, root_url, page_path

我发现我仍然需要用 item.specific.get_url 渲染页面 urls。 item.url 不行。

发生这种情况是因为页面模型上的 url 属性 是 defined by this line of code:

url = property(get_url)

即定义一个 属性 url 来包装对 get_url 函数 的调用,因为它在该行代码为 运行[=35= 的那一刻存在] - 即 Page.get_url 的默认实现。即使您在 Node 模型上覆盖 get_url,Node 模型的 url 属性 仍将指向原始定义。

如果您在定义 get_url 之后添加行 url = property(get_url),或者直接在您的模板上调用 {{ item.specific.get_url }},您应该会看到所需的行为。

根据文档,如果您要设置自定义 URL 方案,建议使用 get_url_parts 覆盖方法,因为它包含所有 URL 通用的共享逻辑]访问器(urlget_urlfull_urlrelative_url)。