我希望能够将标记添加到我创建的自定义 StructBlock。
现在的模型是这样的
class MapsIndicatorBlock(blocks.StructBlock):
text_icon = blocks.CharBlock(
label='Maps/Indicators Text or Icon',
required=False
)
pop_up_title = blocks.CharBlock(
label='Pop-Up Title',
required=False
)
pop_up_text = blocks.RichTextBlock(
label ='Pop-Up Text/Image',
required=False
)
pop_up_colour = blocks.CharBlock(
choices=constants.BOOTSTRAP4_BUTTON_COLOUR_CHOICES,
default='btn btn-primary',
max_length=128,
required=False
)
tags = TaggableManager()
objects = models.Manager()
class Meta:
template = 'cityregiontable/map_indicator_block.html'
TaggableManager() 设计用于 models.model 而不是 blocks.StructBlock。
我尝试创建一种使用以下方法创建标签的方法,但无济于事。我收到错误 RE:无法找到 MapsIndicatorBlock 的模型。这是正确的,因为 MapsIndicatorBlock 是一个 block ,而不是一个模型。
class MITag(TaggedItemBase):
content_object = models.ForeignKey(
'MapsIndicatorBlock',
on_delete=models.CASCADE,
related_name='tagged_mi_block'
)
我怎样才能让一个 block 有元数据标签?
最佳答案
基于 custom block types 的文档作为起点,我们能够生成一个利用现有 Wagtail AdminTagWidget
的自定义 FieldBlock
.
这个小部件几乎可以为您完成所有工作,它会提取可用的标签以进行自动完成,并且会保存任何即时创建的新标签。
可以读取这些标签并使用模型 @property
或类似的方式更方便地使用它们。请记住,Streamfields 将数据存储为 JSON,因此您不会立即获得任何模型/数据库链接。
限制
需要注意的是,保存的标签存储为原始字符串,这意味着如果您有一些更复杂的标签用例,您将需要做更多的工作才能将其集成。例如一个标签页面,显示所有使用该标签的页面或 Wagtail 的 ModelAdmin
中的高级标签编辑。
在这些情况下,您可以想出一种方法来将页面的标记与 StreamField 标记“同步”,也可以将此工作抽象为混合。或者,您可以在标签页面上修改查询,以将那些包含您想要的流场数据的查询也包含在内。
示例代码
from itertools import chain
from django import forms
from wagtail.admin.edit_handlers import FieldPanel, StreamFieldPanel
from wagtail.admin.widgets import AdminTagWidget
from wagtail.core.blocks import CharBlock, FieldBlock, StructBlock, RichTextBlock
from wagtail.core.fields import StreamField
from wagtail.core.models import Page
class TagsBlock(FieldBlock):
"""
Basic Stream Block that will use the Wagtail tags system.
Stores the tags as simple strings only.
"""
def __init__(self, required=False, help_text=None, **kwargs):
# note - required=False is important if you are adding this tag to an existing streamfield
self.field = forms.CharField(widget=AdminTagWidget, required=False)
super().__init__(**kwargs)
class MapBlock(StructBlock):
title = CharBlock(label="Title", required=False)
content = RichTextBlock(label="Content", required=False)
tags = TagsBlock(label="Tags", required=False)
class Meta:
icon = 'site'
class LocationPage(Page):
"""
Detail for a specific location.
"""
# ... other fields
# this is the stream field added
map_info = StreamField([('Map', MapBlock(required=False))], blank=True)
@property
def get_tags(self):
"""
Helpful property to pull out the tags saved inside the struct value
Important: makes some hard assumptions about the names & structure
Does not get the id of the tag, only the strings as a list
"""
tags_all = [block.value.get('tags', '').split(',') for block in self.test_b]
tags = list(chain.from_iterable(tags_all))
return tags
# Fields to show to the editor in the admin view
content_panels = [
FieldPanel('title', classname="full"),
StreamFieldPanel('map_info'),
# ... others
]
# ... rest of page model
感谢this similar question about tags in streamfields ,回答这个问题帮助我回答了这个问题。 Creating a TagsBlock for StreamField
关于django - 将标签放入 StructBlock,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61231112/