在继承的类中扩展wagtail Streamfields

时间:2017-01-08 21:31:47

标签: python django wagtail

我有一个抽象类,其中包含了StreamField。我还有一个继承自BasePage的类CustomPage。我希望CustomPage向内容添加新的StructBlock。我该怎么做?

class BasePage(Page):
    content = StreamField([
        ('ad', ...),
        ('text', ...),
        ('img', ...),
    ])
    content_panels = Page.content_panels + [
        StreamFieldPanel('content'),
    ]

    class Meta:
        abstract = True

class CustomPage(BasePage):
    # add ('custom_block', ...) to content streamfield.

2 个答案:

答案 0 :(得分:3)

StreamField定义不能以这种方式直接“扩展”,但通过一些重新混洗,您可以定义一个重新使用相同阻止列表的新StreamField:

COMMON_BLOCKS = [
    ('ad', ...),
    ('text', ...),
    ('img', ...),
]

class BasePage(Page):
    content = StreamField(COMMON_BLOCKS)
    ...

class CustomPage(BasePage):
    content = StreamField(COMMON_BLOCKS + [
        ('custom_block', ...),
    ])

或者在StreamBlock上使用继承(你可能认为它比连接列表更简洁:

class CommonStreamBlock(StreamBlock):
    ad = ...
    text = ...
    img = ...

class CustomStreamBlock(CommonStreamBlock):
    custom_block = ...

class BasePage(Page):
    content = StreamField(CommonStreamBlock())
    ...

class CustomPage(BasePage):
    content = StreamField(CustomStreamBlock())

另请注意,这是only possible since Django 1.10 - 旧版本的Django不允许覆盖抽象超类的字段。

答案 1 :(得分:0)

我在@gasman解决方案旁边找到了另一个解决方案。

它使用Stream字段中的deconstruct方法从BasePage StreamField获取所有块。它在CustomPage中创建内容StreamField时使用这些块。

我现在会使用这个,但我认为@gasman最后的解决方案是最美丽的解决方案。

class BasePage(Page):
    content = StreamField([
        ('ad', ...),
        ('text', ...),
        ('img', ...),
    ])
    content_panels = Page.content_panels + [
        StreamFieldPanel('content'),
    ]
    @staticmethod
    def get_content_blocks():
        return list(BasePage.content.field.deconstruct()[2][0])

    class Meta:
        abstract = True

class CustomPage(BasePage):
    content = StreamField(BasePage.get_content_blocks() +
        [
            ('custom_block', ....),
        ]
    )