admin管理员组

文章数量:1399933

Background

I try to import some datas from a wordpress website into a new Wagtail one. I made a script that iterate on my data from wordpress and I check the type and then try to transform data into a StreamChild/StructBlock to insert it into my body which is a StreamField.

Problem

I don't get how to transform a certain block that contains a StreamBlock itself.

This is my block definition :

class InternalLinkBlock(blocks.StructBlock):
    page = PageChooserBlock()
    title = blocks.CharBlock()


class ExternalLinkBlock(blocks.StructBlock):
    link = blocks.URLBlock()
    title = blocks.CharBlock()


class LinkStreamBlock(blocks.StreamBlock):
    internal = InternalLinkBlock()
    external = ExternalLinkBlock()

class ButtonBlock(block.StructBlock):
    title = block.CharBlock()
    cta = LinkStreamBlock()
    with_background = blocks.BooleanBlock()

class StoryBlock(blocks.StreamBlock):
    button = ButtonBlock()

And how I try to insert it in my script :

    if block["blockName"] == "button_block":
        new_block = (
            "button",
            {
                "title": "coucou",
                "with_background": True,
                "cta": [(
                    "external",
                    {"link": "google", "title": "cta_text"}),
                ]
            },
        )
        page.body.append(new_block)
    new_page = page.save_revision()

I get this error in save : AttributeError: 'tuple' object has no attribute 'get_prep_value'

I can't figure out how to insert my data. Can you help me please?

Background

I try to import some datas from a wordpress website into a new Wagtail one. I made a script that iterate on my data from wordpress and I check the type and then try to transform data into a StreamChild/StructBlock to insert it into my body which is a StreamField.

Problem

I don't get how to transform a certain block that contains a StreamBlock itself.

This is my block definition :

class InternalLinkBlock(blocks.StructBlock):
    page = PageChooserBlock()
    title = blocks.CharBlock()


class ExternalLinkBlock(blocks.StructBlock):
    link = blocks.URLBlock()
    title = blocks.CharBlock()


class LinkStreamBlock(blocks.StreamBlock):
    internal = InternalLinkBlock()
    external = ExternalLinkBlock()

class ButtonBlock(block.StructBlock):
    title = block.CharBlock()
    cta = LinkStreamBlock()
    with_background = blocks.BooleanBlock()

class StoryBlock(blocks.StreamBlock):
    button = ButtonBlock()

And how I try to insert it in my script :

    if block["blockName"] == "button_block":
        new_block = (
            "button",
            {
                "title": "coucou",
                "with_background": True,
                "cta": [(
                    "external",
                    {"link": "google", "title": "cta_text"}),
                ]
            },
        )
        page.body.append(new_block)
    new_page = page.save_revision()

I get this error in save : AttributeError: 'tuple' object has no attribute 'get_prep_value'

I can't figure out how to insert my data. Can you help me please?

Share Improve this question asked Mar 25 at 9:59 Lucie LaporteLucie Laporte 233 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 2

This is due to an oversight that has been fixed for the forthcoming Wagtail 6.5 release - appending to a StreamField is supposed to accept any reasonable data type (such as the "list of (block type, value) tuples" representation for a StreamBlock), but currently only accepts the specific data type used internally by the block - which for StreamBlock is an instance of the custom StreamValue class. Your code should hopefully work for Wagtail 6.5 onward.

As a workaround, you can modify your code to pass "cta" as a StreamValue instance:

from wagtail.blocks import StreamValue

cta_block_def = ButtonBlock.base_blocks["cta"]

# ...

    if block["blockName"] == "button_block":
        new_block = (
            "button",
            {
                "title": "coucou",
                "with_background": True,
                "cta": StreamValue(
                    cta_block_def,
                    [(
                        "external",
                        {"link": "google", "title": "cta_text"}),
                    ],
                ),
            },
        )
        page.body.append(new_block)
    new_page = page.save_revision()

本文标签: wagtailInsert nested StreamChild into StreamField programmaticallyStack Overflow