默认情况下 Wagtail 的 slug(超链接缩略名)会沿用标题,对于中文频道就比较麻烦,因为超链接中有一段中文,从视觉效果和链接长度上来讲都不大科学。

可以通过重写 clean() 方法实现在保存页面之前,覆盖默认的 slug 等项的值:

import time
from django.utils.text import slugify

class NewsPage(Page):
    title_pic = models.ForeignKey(
        'wagtailimages.Image',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+',
    )
    intro = models.CharField('摘要', blank=True, max_length=250)
    body = RichTextField()

    content_panels = Page.content_panels + [
        FieldPanel('intro', classname='full'),
        FieldPanel('body', classname='full'),
        ImageChooserPanel('title_pic'),
    ]

    # 用日期格式覆盖默认 slug
    def clean(self):
        super().clean()
        custom_slug = time.strftime("%y%m%d-%H%M%S", time.localtime())
        self.slug = slugify(custom_slug)
        
# 设置 slug 默认值
NewsPage._meta.get_field('slug').default = time.strftime("%Y%m%d-%H%M%S", time.localtime())

注意最后一行与上面的 NewsPage 类处在相同层级上

添加子页面时,页面 url 的形式大概是 https://www.sample.com/news/20190722-140903

编辑后超链接发生变化

我发现上述代码虽然可以解决 slug 自动采用预定义格式复写,但当重新编辑页面后,页面的 slug 会根据当前时间生成新的。这样就导致超链接发生了变化,这可不是我们期待的效果。

解决方法是通过页面的 first_published_at 属性进行判断,设置一个判断,只要页面不存在这个属性,则采用自动生成的超链接,否则就不让 clean() 方法工作:

# 用日期格式覆盖默认 slug
class NewsPage(Page):
    ...
    def clean(self):
        if not super().first_published_at:
            super().clean()
            custom_slug = time.strftime("%y%m%d-%H%M%S", time.localtime())
            self.slug = slugify(custom_slug)

Reference