На основе документов для пользовательских типов блоков в качестве отправной точки мы можем создать пользовательский FieldBlock
, который использует существующую трясогузку AdminTagWidget
.
Этот виджет выполняет почти всю работу за вас, он извлекает доступные теги для автозаполнения, а также сохраняет все новые теги, созданные на лету.
Можно считывать эти теги и делать их доступно более удобно с моделью @property
или аналогичной. Помните, что Streamfields хранит данные как JSON, поэтому вы не получите никаких ссылок на модель / базу данных из коробки.
Ограничения
Предупреждение: сохраненные теги сохраняются как необработанные strings, это означает, что если у вас есть более сложные варианты использования тегов, вам придется проделать немного больше работы, чтобы интегрировать их. например, страница тега, которая показывает все страницы, которые используют этот тег или расширенное редактирование тега в Wagtail ModelAdmin
.
. В этих случаях вы можете либо найти способ «синхронизировать c» тегов страницы с тег 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
Благодаря этот похожий вопрос о тегах в streamfields , отвечая, что помог мне ответить на этот. Создание блока тегов для StreamField