如何覆盖默认的 wagtail slug 生成?
How to override default wagtail slug generation?
我正在尝试创建一个博客,其中的博客-post 将包含以下内容:
example.com/blog/title-01012021/,其中日期 - 是发布日期。
如何覆盖默认的鹡鸰蛞蝓生成?
Wagtail 提供了几种用于 slug 可用性检查和唯一 slug 生成的方法:
def _slug_is_available(slug, parent_page, page=None):
if parent_page is None:
# the root page's slug can be whatever it likes...
return True
siblings = parent_page.get_children()
if page:
siblings = siblings.not_page(page)
return not siblings.filter(slug=slug).exists()
def _get_autogenerated_slug(self, base_slug):
candidate_slug = base_slug
suffix = 1
parent_page = self.get_parent()
while not Page._slug_is_available(candidate_slug, parent_page, self):
# try with incrementing suffix until we find a slug which is available
suffix += 1
candidate_slug = "%s-%d" % (base_slug, suffix)
return candidate_slug
def full_clean(self, *args, **kwargs):
# Apply fixups that need to happen before per-field validation occurs
if not self.slug:
# Try to auto-populate slug from title
allow_unicode = getattr(settings, 'WAGTAIL_ALLOW_UNICODE_SLUGS', True)
base_slug = slugify(self.title, allow_unicode=allow_unicode)
# only proceed if we get a non-empty base slug back from slugify
if base_slug:
self.slug = self._get_autogenerated_slug(base_slug)
if not self.draft_title:
self.draft_title = self.title
# Set the locale
if self.locale_id is None:
self.locale = self.get_default_locale()
super().full_clean(*args, **kwargs)
def clean(self):
super().clean()
if not Page._slug_is_available(self.slug, self.get_parent(), self):
raise ValidationError({'slug': _("This slug is already in use")})
我不知道如何在我的应用中覆盖这些方法。
您可以使用的一种方法是在模型的保存方法中做一些自定义工作
def some_date_method(self):
return datetime.datetime.now()
def save(self, *args, **kwargs):
self.slug = f"{slugify(self.title)}-{self.some_date_method()}"
super().save(*args, **kwargs)
您可以在保存对象之前使用 Django Signals 更改 slug:
from django.db.models.signals import pre_save
@receiver(pre_save)
def set_slug_on_new_instance(sender, instance, **kwargs):
if isinstance(instance, Page):
instance.slug = Whatever value you want
您也可以将 Page
更改为任何您想要为其更换子弹的特定型号。
我找到了适合我的解决方案。 Unidecode 适用于西里尔文段。
from unidecode import unidecode
from django.template import defaultfilters
class HomePage(Page):
date_published = models.DateField(blank=True, null=True)
content = .....
def clean(self):
super().clean()
date = '{:%Y-%m-%d}'.format(self.date_published)
base_slug = defaultfilters.slugify(unidecode(self.title))
self.slug = "%s-%s" % (base_slug, date)
date_widget = widgets.AdminDateInput(
attrs = {
'placeholder': 'yyyy-mm-dd'
}
)
content_panels = Page.content_panels + [
FieldPanel('date_published', widget=date_widget),
StreamFieldPanel('content', classname="full"),
]
我正在尝试创建一个博客,其中的博客-post 将包含以下内容: example.com/blog/title-01012021/,其中日期 - 是发布日期。 如何覆盖默认的鹡鸰蛞蝓生成?
Wagtail 提供了几种用于 slug 可用性检查和唯一 slug 生成的方法:
def _slug_is_available(slug, parent_page, page=None):
if parent_page is None:
# the root page's slug can be whatever it likes...
return True
siblings = parent_page.get_children()
if page:
siblings = siblings.not_page(page)
return not siblings.filter(slug=slug).exists()
def _get_autogenerated_slug(self, base_slug):
candidate_slug = base_slug
suffix = 1
parent_page = self.get_parent()
while not Page._slug_is_available(candidate_slug, parent_page, self):
# try with incrementing suffix until we find a slug which is available
suffix += 1
candidate_slug = "%s-%d" % (base_slug, suffix)
return candidate_slug
def full_clean(self, *args, **kwargs):
# Apply fixups that need to happen before per-field validation occurs
if not self.slug:
# Try to auto-populate slug from title
allow_unicode = getattr(settings, 'WAGTAIL_ALLOW_UNICODE_SLUGS', True)
base_slug = slugify(self.title, allow_unicode=allow_unicode)
# only proceed if we get a non-empty base slug back from slugify
if base_slug:
self.slug = self._get_autogenerated_slug(base_slug)
if not self.draft_title:
self.draft_title = self.title
# Set the locale
if self.locale_id is None:
self.locale = self.get_default_locale()
super().full_clean(*args, **kwargs)
def clean(self):
super().clean()
if not Page._slug_is_available(self.slug, self.get_parent(), self):
raise ValidationError({'slug': _("This slug is already in use")})
我不知道如何在我的应用中覆盖这些方法。
您可以使用的一种方法是在模型的保存方法中做一些自定义工作
def some_date_method(self):
return datetime.datetime.now()
def save(self, *args, **kwargs):
self.slug = f"{slugify(self.title)}-{self.some_date_method()}"
super().save(*args, **kwargs)
您可以在保存对象之前使用 Django Signals 更改 slug:
from django.db.models.signals import pre_save
@receiver(pre_save)
def set_slug_on_new_instance(sender, instance, **kwargs):
if isinstance(instance, Page):
instance.slug = Whatever value you want
您也可以将 Page
更改为任何您想要为其更换子弹的特定型号。
我找到了适合我的解决方案。 Unidecode 适用于西里尔文段。
from unidecode import unidecode
from django.template import defaultfilters
class HomePage(Page):
date_published = models.DateField(blank=True, null=True)
content = .....
def clean(self):
super().clean()
date = '{:%Y-%m-%d}'.format(self.date_published)
base_slug = defaultfilters.slugify(unidecode(self.title))
self.slug = "%s-%s" % (base_slug, date)
date_widget = widgets.AdminDateInput(
attrs = {
'placeholder': 'yyyy-mm-dd'
}
)
content_panels = Page.content_panels + [
FieldPanel('date_published', widget=date_widget),
StreamFieldPanel('content', classname="full"),
]