django - 将标签放入 StructBlock

标签 django django-models tags wagtail

我希望能够将标记添加到我创建的自定义 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/

相关文章:

python - 使用 boto3 从 s3 下载时使用文件名作为文件名

django - 弃用 Django 模型中的字段

Django 更新表单

amazon-web-services - 如何在由 elastic-beanstalk 创建的 ec2 实例上设置标签

javascript - 如何创建没有名称的 "Empty"<Label> 标记

javascript - 如何使用文件上传对话框选择的绝对文件路径的值填充 &lt;input type ="text">?

python - 导入错误 : cannot import name RemovedInDjango19Warning

javascript - 在for循环Angular2 Django中获取多个可观察请求

python - Django : ManyToMany relation error ( object has no attribute)

html - 中心标签仍然有效吗?