如何覆盖Wagtail默认slug生成规则,实现包含发布日期的博文slug
覆盖Wagtail默认slug生成规则的实现方法
你不需要修改Wagtail核心源码,直接在自定义的博客页面模型中重写对应方法即可实现标题-发布日期格式的slug,具体操作如下:
1. 导入依赖模块
在你博客应用的models.py文件头部添加需要的导入:
from django.utils.text import slugify from django.utils import timezone from django.conf import settings from wagtail.models import Page
2. 重写博客页面模型的slug生成逻辑
找到你继承Wagtail Page的博文模型(一般命名为BlogPage),重写_get_autogenerated_slug和full_clean两个方法:
class BlogPage(Page): # 你的原有字段,比如发布日期、正文、封面等,注意必须要有发布日期字段 publish_date = models.DateField("发布日期", default=timezone.now) # 其余原有字段保持不变... def _get_autogenerated_slug(self, base_slug): # 按照要求拼接日期后缀,格式为ddmmyyyy date_suffix = self.publish_date.strftime("%d%m%Y") candidate_slug = f"{base_slug}-{date_suffix}" suffix = 1 parent_page = self.get_parent() # 同天有相同标题的博文时,自动追加数字后缀避免slug重复 while not Page._slug_is_available(candidate_slug, parent_page, self): suffix += 1 candidate_slug = f"{base_slug}-{date_suffix}-{suffix}" return candidate_slug def full_clean(self, *args, **kwargs): # 在父类校验执行前先生成自定义格式的slug if not self.slug: allow_unicode = getattr(settings, 'WAGTAIL_ALLOW_UNICODE_SLUGS', True) base_slug = slugify(self.title, allow_unicode=allow_unicode) if base_slug: self.slug = self._get_autogenerated_slug(base_slug) # 执行父类原有校验逻辑,此时slug已赋值,不会被默认逻辑覆盖 super().full_clean(*args, **kwargs)
注意事项
- 如果发布日期支持后台手动编辑,确保保存时
publish_date已完成赋值,避免日期后缀生成错误 - 已发布的存量博文不会自动更新slug,可手动调整或编写批量迁移脚本处理
- 不需要同天同标题博文的自动后缀可以删除循环校验逻辑,但可能出现slug重复报错,建议保留
- 如需调整日期格式,修改
strftime的参数即可,比如%Y%m%d对应年月日格式 - 该实现完全基于Wagtail原生扩展机制,不修改核心源码,后续版本升级不受影响
内容的提问来源于stack exchange,提问作者Ubo
相关产品推荐
相关产品推荐

