Skip to main content
 首页 » 编程设计

python之Wagtail 页面标题覆盖

2025年05月04日13youxin

我上面有这个模型,我想去掉标题。或者重命名它。其实比赛号码本身就是这个型号的名称。所以我需要以下选项之一:

  • 将标题重命名为“匹配编号”
  • 将自定义帮助文本添加到标题“添加匹配项”
  • 删除标题

我的模型:

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"), 
    ] 

请您参考如下方法:

实现此目的的一种方法是从 content_panels 中实际删除 title。然后在页面的 clean 方法中手动创建 title 和 slug 字段。您还需要为模型设置默认的 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 模型分开)必须具有某些字段(标题,slug)。编辑界面还在客户端构建 slug 字段(在 Javascript 中),它依赖于存在的 title 字段。

因此,您必须自己负责生成 title 和 slug 字段。重要的是 slug 字段既是唯一的又是 slugfied 的。

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

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

请记住,Wagtail 不会以任何方式规定您如何使用 title 字段来呈现模板。实际上只有模型限制和管理界面假定存在标题。

在 Wagtail Github 页面上有一个关于这个项目的旧的和持续的讨论:https://github.com/wagtail/wagtail/issues/161

代码挑剔

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