当前位置:  开发笔记 > 编程语言 > 正文

使用额外字段扩展Wagtail抽象模型的正确方法是什么?

如何解决《使用额外字段扩展Wagtail抽象模型的正确方法是什么?》经验,为你挑选了1个好方法。

我有一个带有几个StreamFields 的抽象Wagtail模型.其中两个StreamField位于管理视图中的单独选项卡中,这些选项卡将添加到edit_handler.

class AbstractHomePage(Page):
    body = StreamField(
        HomePageStreamBlock(),
        default=''
    )
    headingpanel = StreamField(
        HeadingPanelStreamBlock(),
        default=''
    )
    sidepanel = StreamField(
        SidePanelStreamBlock(),
        default=''
    )

    class Meta:
        abstract = True

    search_fields = Page.search_fields + [index.SearchField('body')]

    content_panels = Page.content_panels + [
        StreamFieldPanel('body'),
    ]

    pagesection_panels = [
        StreamFieldPanel('headingpanel'),
        StreamFieldPanel('sidepanel'),
    ]

    edit_handler = TabbedInterface([
        ObjectList(content_panels),
        ObjectList(pagesection_panels, heading='Page sections'),
        ObjectList(Page.promote_panels),
        ObjectList(Page.settings_panels, classname='settings'),
    ])

我想扩展此模型并添加一个字段:

class Foo(AbstractHomePage):
    extra = models.TextField()

    Meta:
        verbose_name='Foo'

    content_panels = [
        AbstractHomePage.content_panels[0],     # title
        FieldPanel('extra'),
        AbstractHomePage.content_panels[-1]     # streamfield
    ]

添加新的Foo页面时,管理面板中可用的唯一字段是来自的字段AbstractHomePage.直到我更新新添加的字段不可用Fooedit_handler:

class Foo(AbstractHomePage):
    extra = models.TextField()

    Meta:
        verbose_name='Foo'

    content_panels = [
        AbstractHomePage.content_panels[0],     # title
        FieldPanel('extra'),
        AbstractHomePage.content_panels[-1]     # streamfield
    ]

    edit_handler = TabbedInterface([
        ObjectList(content_panels),
        ObjectList(AbstractHomePage.pagesection_panels, heading='Page sections'),
        ObjectList(Page.promote_panels),
        ObjectList(Page.settings_panels, classname='settings'),
    ])

现在我的问题是:我做错了什么或没有遵循良好的编码习惯?

如果我必须更新edit_handler每个扩展模型,有没有更好的方法来做到这一点?必须确保扩展模型的新添加字段每次AbstractHomePage都会获得明确的"样板" edit_handler块,感觉非常难看.我认为这是对DRY原则的严重违反.



1> gasman..:

你必须重新定义的原因edit_handlerFoo是Python的评估AbstractHomePage类定义从上到下-在它遇到行点:

ObjectList(content_panels),

content_panels被视为变量,而不是类属性,因此编辑处理程序是基于content_panels该点存在的列表构建的.content_panels在子类中重新定义不能覆盖它.

从本质上讲,您正在寻找一种方法来推迟构建edit_handler,直到定义了子类.我无法直接看到这样做的好方法,但我认为你可以通过重写方法来对Page.get_edit_handler Wagtail内部进行一些挖掘来实现它:

from wagtail.utils.decorators import cached_classmethod

class AbstractHomePage(Page):
    ...
    @cached_classmethod
    def get_edit_handler(cls):
        edit_handler = TabbedInterface([
            ObjectList(cls.content_panels),
            ObjectList(cls.pagesection_panels, heading='Page sections'),
            ObjectList(cls.promote_panels),
            ObjectList(cls.settings_panels, classname='settings'),
        ])
        return edit_handler.bind_to_model(cls)

推荐阅读
落单鸟人
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有