在继承的 class 中扩展 wagtail Streamfields
Extending wagtail Streamfields in an inherited class
我有一个摘要 class,其中包含 ha StreamField。我还有一个继承自 BasePage 的 class 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.
StreamField 定义不能以这种方式直接'extended',但通过一些重新洗牌,您可以定义一个重新使用相同块列表的新 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 不允许覆盖抽象超类的字段。
除@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', ....),
]
)
我有一个摘要 class,其中包含 ha StreamField。我还有一个继承自 BasePage 的 class 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.
StreamField 定义不能以这种方式直接'extended',但通过一些重新洗牌,您可以定义一个重新使用相同块列表的新 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 不允许覆盖抽象超类的字段。
除@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', ....),
]
)