ohad guetta
ohad guetta

Reputation: 9

Appending object To StructBlock inside StreamField Wagtail

trying to create new task dynamically in my project on wagtail using StreamField and StructBlock but without success.

Please help me, I'm losing my mind over this. The user sets some parameters in the template and then supposed to create a new task...

I tried three different options but this came out. I have with and without json.dumps and converting it into a StreamField or StructBlock Really losing my mind😀

this is my code:

models.py:

tasks = StreamField([
        ("task", blocks.StructBlock([
            ("name", blocks.CharBlock(required=True, max_length=150)),
            ("description", blocks.RichTextBlock(required=False)),
            ("image", ImageChooserBlock(required=False)),
            ("subtasks", blocks.ListBlock(blocks.StructBlock([
                ("name", blocks.CharBlock(required=True, max_length=150)),
                ("description", blocks.RichTextBlock(required=False)),
            ])))
        ]))
    ],null=True,blank=True,use_json_field=True)
    

views:

def create_task(request, project_id):
    # create a new task
    project = Project.objects.get(pk=project_id)


    # new_task = {
    #     "name": request.POST["task_name"],
    #     "description": str(request.POST["task_description"]),
    #     "image": None,
    #     "subtasks": [],
    # }
    # project.tasks.append(json.dumps(new_task))
#       \Lib\site-packages\wagtail\blocks\stream_block.py", line 610, in _construct_stream_child     
#     type_name, value = item
#     ^^^^^^^^^^^^^^^^
# ValueError: too many values to unpack (expected 2)
    

    

    # new_task = ('task',{
    #     "name": request.POST["task_name"],
    #     "description": str(request.POST["task_description"]),
    #     "image": None,
    #     "subtasks": [],
    # })
    # project.tasks.append(json.dumps(new_task))
#       \Lib\site-packages\wagtail\blocks\stream_block.py", line 610, in _construct_stream_child     
#     type_name, value = item
#     ^^^^^^^^^^^^^^^^
# ValueError: too many values to unpack (expected 2)



    new_task = {
        'type': 'task', 'value': {
            'type': 'name','value': request.POST['task_description'],
            'type': 'description','value': RichText(request.POST['task_description']),
            'type': 'image','value': None,
            'type': 'subtasks','value': [],
        }
    }
    project.tasks.append(json.dumps(new_task))
#         type_name, value = item
#     ^^^^^^^^^^^^^^^^
# ValueError: too many values to unpack (expected 2)
    
    

    project.save_revision(
        submitted_for_moderation=False,
        approved_go_live_at=None,
        changed=True,
        log_action=True,
        previous_revision=None,
        clean=True,
    ).publish()
    return JsonResponse({"status": "success"})

Upvotes: 0

Views: 102

Answers (1)

gasman
gasman

Reputation: 25227

As mentioned in the StreamField documentation, the value to append to the field should be a tuple of (block_type, value). You do not need to JSON-encode it (because then you'll be appending a string, not a tuple).

Additionally, the value of a RichTextBlock should be an instance wagtail.rich_text.RichText, rather than a string.

from wagtail.rich_text import RichText

new_task = ('task',{
    "name": request.POST["task_name"],
    "description": RichText(request.POST["task_description"]),
    "image": None,
    "subtasks": [],
})
project.tasks.append(new_task)

Upvotes: 0

Related Questions