wagtail-deprecated / wagtail-react-streamfield

Powerful field for inserting multiple blocks with nesting. (NO LONGER MAINTAINED - See Wagtail 2.13 Release Notes)

Home Page:https://wagtail.github.io/react-streamfield/public/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

ListBlock breaks when a sub-block throws a validation error

dougfir-lc opened this issue · comments

When a child block of ListBlock raises a validation error, an AttributeError is thrown during rendering of the invalid form.

Version: 1.1.1

Steps to Reproduce:
-Add a list block to a page.
-Save the page while a block in ListBlock is in an invalid state.

Result: An error occurs during template rendering "AttributeError: 'list' object has no attribute 'get'"

Expected Result: The page displays the validation error and marks the invalid fields.

Example Code:

class TestStreamBlock(StreamBlock):
    names = ListBlock(CharBlock(max_length=50))

class TestPage(Page):
    content = StreamField(TestStreamBlock(required=False),blank=True)

    content_panels = Page.content_panels + [
        StreamFieldPanel('content'),
    ]

Having the exact same issue on version 1.1.1

Fixed by wagtail/wagtail@b36564f, will be in a new version of wagtail-react-streamfield today.

Released in version 1.2.0.

I got the same error now, using 1.3.4.

File "C:\virtualenv\wagtailcms\lib\site-packages\wagtail_react_streamfield\blocks\struct_block.py" in prepare_value
66. else children_errors.get(k))
Exception Type: AttributeError at /admin/pages/3/edit/
Exception Value: 'list' object has no attribute 'get'

The block itself is quite simple:

class TopNewsItem(BaseBlockMixin, blocks.StructBlock):
    date = blocks.CharBlock(label=_('Date (or tag)'), required=False)
    title = blocks.CharBlock(label=_('Title'), required=True)
    subtitle = blocks.CharBlock(label=_('Subtitle'), required=False)
    picture = ImageChooserBlock(label=_('Picture'), required=True)
    label = blocks.CharBlock(label=_('Tab label'), required=False)

    details_url = blocks.URLBlock(label=_('Link to details page'), required=False)

    class Meta:
        closed = True


class TopNewsBlock(BaseBlockMixin, blocks.ListBlock):
    class Meta:
        icon = "media"
        closed = True

Used as:

body = StreamField(
    ('topnews', TopNewsBlock(label=_("Top carousel block"),  child_block=TopNewsItem(label=_("Carousel element"))))
    blank=True, 
    null=True
)

Wagtail 2.6.1, wagtail-react-streamfield 1.3.4

Full traceback:

File "C:\virtualenv\wagtailcms\lib\site-packages\django\core\handlers\exception.py" in inner
  34.             response = get_response(request)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\core\handlers\base.py" in _get_response
  115.                 response = self.process_exception_by_middleware(e, request)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\core\handlers\base.py" in _get_response
  113.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\views\decorators\cache.py" in _wrapped_view_func
  44.         response = view_func(request, *args, **kwargs)

File "C:\virtualenv\wagtailcms\lib\site-packages\wagtail\admin\urls\__init__.py" in wrapper
  102.             return view_func(request, *args, **kwargs)

File "C:\virtualenv\wagtailcms\lib\site-packages\wagtail\admin\decorators.py" in decorated_view
  34.             return view_func(request, *args, **kwargs)

File "C:\virtualenv\wagtailcms\lib\site-packages\wagtail\admin\views\pages.py" in edit
  545.         'has_unsaved_changes': has_unsaved_changes,

File "C:\virtualenv\wagtailcms\lib\site-packages\django\shortcuts.py" in render
  36.     content = loader.render_to_string(template_name, context, request, using=using)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\loader.py" in render_to_string
  62.     return template.render(context, request)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\backends\django.py" in render
  61.             return self.template.render(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\base.py" in render
  171.                     return self._render(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\base.py" in _render
  163.         return self.nodelist.render(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\base.py" in render
  937.                 bit = node.render_annotated(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\base.py" in render_annotated
  904.             return self.render(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\loader_tags.py" in render
  150.             return compiled_parent._render(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\base.py" in _render
  163.         return self.nodelist.render(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\base.py" in render
  937.                 bit = node.render_annotated(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\base.py" in render_annotated
  904.             return self.render(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\loader_tags.py" in render
  150.             return compiled_parent._render(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\base.py" in _render
  163.         return self.nodelist.render(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\base.py" in render
  937.                 bit = node.render_annotated(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\base.py" in render_annotated
  904.             return self.render(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\loader_tags.py" in render
  150.             return compiled_parent._render(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\base.py" in _render
  163.         return self.nodelist.render(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\base.py" in render
  937.                 bit = node.render_annotated(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\base.py" in render_annotated
  904.             return self.render(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\loader_tags.py" in render
  150.             return compiled_parent._render(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\base.py" in _render
  163.         return self.nodelist.render(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\base.py" in render
  937.                 bit = node.render_annotated(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\base.py" in render_annotated
  904.             return self.render(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\loader_tags.py" in render
  150.             return compiled_parent._render(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\base.py" in _render
  163.         return self.nodelist.render(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\base.py" in render
  937.                 bit = node.render_annotated(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\base.py" in render_annotated
  904.             return self.render(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\loader_tags.py" in render
  62.                 result = block.nodelist.render(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\base.py" in render
  937.                 bit = node.render_annotated(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\base.py" in render_annotated
  904.             return self.render(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\loader_tags.py" in render
  62.                 result = block.nodelist.render(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\base.py" in render
  937.                 bit = node.render_annotated(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\base.py" in render_annotated
  904.             return self.render(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\base.py" in render
  987.             output = self.filter_expression.resolve(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\base.py" in resolve
  671.                 obj = self.var.resolve(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\base.py" in resolve
  796.             value = self._resolve_lookup(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\base.py" in _resolve_lookup
  858.                             current = current()

File "C:\virtualenv\wagtailcms\lib\site-packages\wagtail\admin\edit_handlers.py" in render_form_content
  252.         return mark_safe(self.render_as_object() + self.render_missing_fields())

File "C:\virtualenv\wagtailcms\lib\site-packages\wagtail\admin\edit_handlers.py" in render_as_object
  220.         return self.render()

File "C:\virtualenv\wagtailcms\lib\site-packages\wagtail\admin\edit_handlers.py" in render
  324.             'self': self

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\loader.py" in render_to_string
  62.     return template.render(context, request)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\backends\django.py" in render
  61.             return self.template.render(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\base.py" in render
  171.                     return self._render(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\base.py" in _render
  163.         return self.nodelist.render(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\base.py" in render
  937.                 bit = node.render_annotated(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\base.py" in render_annotated
  904.             return self.render(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\defaulttags.py" in render
  209.                     nodelist.append(node.render_annotated(context))

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\base.py" in render_annotated
  904.             return self.render(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\base.py" in render
  987.             output = self.filter_expression.resolve(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\base.py" in resolve
  671.                 obj = self.var.resolve(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\base.py" in resolve
  796.             value = self._resolve_lookup(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\base.py" in _resolve_lookup
  858.                             current = current()

File "C:\virtualenv\wagtailcms\lib\site-packages\wagtail\admin\edit_handlers.py" in render_as_object
  220.         return self.render()

File "C:\virtualenv\wagtailcms\lib\site-packages\wagtail\admin\edit_handlers.py" in render
  324.             'self': self

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\loader.py" in render_to_string
  62.     return template.render(context, request)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\backends\django.py" in render
  61.             return self.template.render(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\base.py" in render
  171.                     return self._render(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\base.py" in _render
  163.         return self.nodelist.render(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\base.py" in render
  937.                 bit = node.render_annotated(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\base.py" in render_annotated
  904.             return self.render(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\defaulttags.py" in render
  209.                     nodelist.append(node.render_annotated(context))

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\base.py" in render_annotated
  904.             return self.render(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\base.py" in render
  987.             output = self.filter_expression.resolve(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\base.py" in resolve
  671.                 obj = self.var.resolve(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\base.py" in resolve
  796.             value = self._resolve_lookup(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\base.py" in _resolve_lookup
  858.                             current = current()

File "C:\virtualenv\wagtailcms\lib\site-packages\wagtail\admin\edit_handlers.py" in render_as_object
  482.             'field': self.bound_field,

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\loader.py" in render_to_string
  62.     return template.render(context, request)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\backends\django.py" in render
  61.             return self.template.render(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\base.py" in render
  171.                     return self._render(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\base.py" in _render
  163.         return self.nodelist.render(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\base.py" in render
  937.                 bit = node.render_annotated(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\base.py" in render_annotated
  904.             return self.render(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\loader_tags.py" in render
  188.             return template.render(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\base.py" in render
  173.                 return self._render(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\base.py" in _render
  163.         return self.nodelist.render(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\base.py" in render
  937.                 bit = node.render_annotated(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\base.py" in render_annotated
  904.             return self.render(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\loader_tags.py" in render
  53.                 result = self.nodelist.render(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\base.py" in render
  937.                 bit = node.render_annotated(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\base.py" in render_annotated
  904.             return self.render(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\base.py" in render
  987.             output = self.filter_expression.resolve(context)

File "C:\virtualenv\wagtailcms\lib\site-packages\django\template\base.py" in resolve
  698.                 new_obj = func(obj, *arg_vals)

File "C:\virtualenv\wagtailcms\lib\site-packages\wagtail\admin\templatetags\wagtailadmin_tags.py" in render_with_errors
  248.             errors=bound_field.errors

File "C:\virtualenv\wagtailcms\lib\site-packages\wagtail_react_streamfield\widgets.py" in render_with_errors
  94.         streamfield_config = self.get_streamfield_config(value, errors=errors)

File "C:\virtualenv\wagtailcms\lib\site-packages\wagtail_react_streamfield\widgets.py" in get_streamfield_config
  89.             'value': self.block_def.prepare_value(value, errors=errors),

File "C:\virtualenv\wagtailcms\lib\site-packages\wagtail_react_streamfield\monkey_patch.py" in inner
  19.             return new_method(*args, **kwargs)

File "C:\virtualenv\wagtailcms\lib\site-packages\wagtail_react_streamfield\blocks\stream_block.py" in prepare_value
  70.                                                    errors=child_errors),

File "C:\virtualenv\wagtailcms\lib\site-packages\wagtail_react_streamfield\monkey_patch.py" in inner
  19.             return new_method(*args, **kwargs)

File "C:\virtualenv\wagtailcms\lib\site-packages\wagtail_react_streamfield\blocks\list_block.py" in prepare_value
  70.                                                         errors=errors),

File "C:\virtualenv\wagtailcms\lib\site-packages\wagtail_react_streamfield\monkey_patch.py" in inner
  19.             return new_method(*args, **kwargs)

File "C:\virtualenv\wagtailcms\lib\site-packages\wagtail_react_streamfield\blocks\struct_block.py" in prepare_value
  66.                             else children_errors.get(k))

Exception Type: AttributeError at /admin/pages/3/edit/
Exception Value: 'list' object has no attribute 'get'