Wigtail页面标题覆盖

时间:2018-02-05 15:22:33

标签: python wagtail

enter image description here

我上面有这个模型,我想删除标题。或者重命名它。实际上匹配编号本身就是这个模型的标题。所以我需要以下选项之一:

  • 将标题重命名为"匹配编号"
  • 将自定义帮助文字添加到标题"添加匹配数"
  • 删除标题

我的模特:

class Match(Page):
    match_number = models.PositiveSmallIntegerField(blank=True)
    team_1 = models.ForeignKey(
        TeamRooster,
        null=True, blank=True,
        on_delete=models.SET_NULL,
        related_name="+",
    )
    team_1_color = ColorField(default='#ff0000', blank=True)
    team_1_score = models.PositiveSmallIntegerField(blank=True)
    team_2 = models.ForeignKey(
        TeamRooster,
        null=True, blank=True,
        on_delete=models.SET_NULL,
        related_name="+",
    )
    team_2_color = ColorField(default='#0066ff', blank=True)
    team_2_score = models.PositiveSmallIntegerField(blank=True)
    match_starts_at = models.DateTimeField()


    parent_page_types = ['Matches']

    content_panels = [
        FieldPanel('title'),
        FieldPanel('match_number', classname="6"),
        FieldPanel('match_starts_at', classname="6"),
        MultiFieldPanel([
            FieldPanel('team_1', classname="12"),
            FieldPanel('team_1_color', classname="6"),
            FieldPanel('team_2_score', classname="6"),
        ], heading="Team 1"),
        MultiFieldPanel([
            FieldPanel('team_2', classname="12"),
            FieldPanel('team_2_color', classname="6"),
            FieldPanel('team_2_score', classname="6"),
        ], heading="Team 2"),
    ]

2 个答案:

答案 0 :(得分:6)

实现此目的的一种方法是从title中删除content_panels。然后在Page的title方法中手动创建slugclean字段。您还需要为模型设置默认的slug值。

实施例

    from django.utils.text import slugify
    # all other imports (Page, models, panels etc)


    class MatchPage(Page):
        """A page that represents a single game match."""

        number = models.IntegerField(
            unique=True,  # must be unique for use in slug
            help_text="Add the unique number of this Match.")
        starts_at = models.DateTimeField(
            blank=True, # allows blank values (ie. not required)
            help_text="Date and time of when this Match starts.")

        content_panels = [
            # title not present, title should NOT be directly editable
            MultiFieldPanel([
                FieldRowPanel([
                    FieldPanel('number', classname="col6"),
                    FieldPanel('starts_at', classname="col6"),
                ]),
            ], 'Match'),
            # other field panels... teams etc
        ]

        def clean(self):
            """Override the values of title and slug before saving."""
            # super(MatchPage, self).clean() # Python 2.X syntax
            super().clean()
            new_title = 'Match %s' % self.number
            self.title = new_title
            self.slug = slugify(new_title)  # slug MUST be unique & slug-formatted


    # set a default blank slug for when the editing form renders
    # we set this after the model is declared
    MatchPage._meta.get_field('slug').default = 'default-blank-slug'

详细

这可能是Wagtail的一个令人困惑的问题,因为Page模型(与您的MatchPage模型分开)必须具有某些字段(title,slug)。编辑界面还在客户端(在Javascript中)构建了slug字段,它依赖于存在的title字段。

因此,您必须自己负责生成titleslug字段。重要的是,段塞区域既独特又有特征。

在示例代码中,没有考虑编辑器手动设置slug本身(在Promote面板中),无论用户将slug设置为什么,它都将覆盖到match-123

title字段可以是任何字符串,但是必需。

请记住,Wagtail没有规定如何以任何方式使用title字段来渲染模板。它只是模型限制和管理界面假定存在标题。

关于此项目的Wagtail Github页面上有一个古老且持续的讨论:https://github.com/wagtail/wagtail/issues/161

Code Nitpicks

  • 将页面模型命名为MySomethingPage,最后用Page命名是一个合理的约定,这有助于您和其他开发人员知道这是一个页面。
  • 您的字段不需要以页面的模型名称为前缀(例如match_somethingmatch_other_thing)。这使得它在路上感到困惑,因为当match_page.match_number更直观地理解时,您必须键入match_page.number。或者,如果您使用此约定,请在match_page.match_team_1等每个字段上使用它。
  • 在您的代码中,您手动创建多个团队,通过相关模型和InlinePanel进行探索可能更好,这意味着更少的代码重复。请参阅有关InlinePanels & Model Clusters
  • 的文档

答案 1 :(得分:0)

要解决@Mark Chackerian发现的问题,您可以为base_form_class页面定义自定义wagtail。 现在,可以覆盖自定义表单的save方法,而不必覆盖模型的clean函数。因此,您不必为每个 w页面设置默认标签:

forms.py

from django import forms
from django.utils.translation import gettext_lazy as _
from django.utils.text import slugify
from django.utils.html import strip_tags
from wagtail.admin.forms import WagtailAdminPageForm


class NoTitleForm(WagtailAdminPageForm):
    title = forms.CharField(required=False, disabled=True, help_text=_('Title is auto-generated.'))
    slug = forms.SlugField(required=False, disabled=True, help_text=_('Slug is auto-generated.'))

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        if not self.initial['title']:
            self.initial['title'] = _('auto-generated-title')
        if not self.initial['slug']:
            self.initial['slug'] = _('auto-generated-slug')

    def save(self, commit=True):
        page = super().save(commit=False)

        new_title = strip_tags(self.cleaned_data['rtf_title'])
        page.title = new_title
        page.slug = slugify(new_title)

        if commit:
            page.save()
        return page

models.py

# ... imports omitted for brevity


class PageWithRtfTitle(Page):

    base_form_class = NoTitleForm
    rtf_title = RichTextField()

    content_panels = Page.content_panels + [
        MultiFieldPanel(
            [
                FieldPanel('rtf_title'),
            ],
            heading=_('Metadata')
    )]
    # ...

不过,对于某些用例,此解决方案可能并不理想。每当标题更改时,两种方法都会覆盖该段。您可能不希望这样做-但可以根据需要调整代码。