Page 1 of 1

Anhängen von Wagtail StructBlock an Streamfield

Posted: 24 Dec 2024, 06:38
by Anonymous
Gibt es eine gute Möglichkeit, einen StructBlock an ein vorhandenes StreamField anzuhängen? Ich erstelle eine Linkseite, auf der Benutzer ohne Administratorrechte ihre eigenen Links hinzufügen können. Ich möchte in der Lage sein, einen LinkBlock mithilfe von Formulardaten anzuhängen. Ich füge bei, was ich gerade habe, und gehe derzeit den Wagtail-Quellcode durch, um besser zu verstehen, wie Blöcke erstellt werden.
class LinkBlock(blocks.StructBlock):
title = blocks.CharBlock(required=True, help_text="Link title")
url = blocks.URLBlock(
required=True,
help_text="Link URL",
)

class LinksPage(Page):
links = StreamField(
[
("link", LinkBlock()),
],
blank=True,
use_json_field=True,
max_length=20
)

content_panels = Page.content_panels + [
FieldPanel("links"),
]

# Adding dynamic links with form data
links_page.links.append(
(
"link",
{
"title": form.cleaned_data["title"],
"url": form.cleaned_data["url"],
"link_type": form.cleaned_data["link_type"],
"color_scheme": form.cleaned_data["color_scheme"],
},
)
)

try:
# TODO: Investigate why this is necessary
# links_page.links._raw_data = [lnk for lnk in links_page.links._raw_data if lnk is not None]
# without the filter above, we get a TypeError when trying to save the page
links_page.save()
except TypeError as e:
logger.error(f"Error saving link: {e}")
raise e

"""
Example stack trace:

File "../.venv/lib/python3.13/site-packages/wagtail/blocks/stream_block.py", line 680, in __getitem__
self._prefetch_blocks(raw_value["type"])
~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^
File "../.venv/lib/python3.13/site-packages/wagtail/blocks/stream_block.py", line 710, in _prefetch_blocks
raw_values = OrderedDict(

File "../.venv/lib/python3.13/site-packages/wagtail/blocks/stream_block.py", line 713, in
if raw_item["type"] == type_name and self._bound_blocks is None
~~~~~~~~^^^^^^^^
TypeError: 'NoneType' object is not subscriptable
"""

Nachdem wir herumgespielt haben, sieht es so aus, als ob diese Methode funktioniert, um einen StructBlock anzuhängen:
links = [(lnk.block_type, lnk.value) for lnk in links_page.links]
links.append(
(
"link",
{
"title": form.cleaned_data["title"],
"url": form.cleaned_data["url"],
"link_type": form.cleaned_data["link_type"],
"color_scheme": form.cleaned_data["color_scheme"],
},
)
)
links_page.links = links

Die Wagtail-Dokumente scheinen jedoch darauf hinzuweisen, dass ein einfaches Anhängen mit dem (Blocktyp, Daten)-Tupel funktionieren sollte. Wäre dankbar für einen Einblick.