Use a dictionary for StreamField errors

Instead of filling an array with `None` to indicate no errors, a
dictionary is only set when there is an actual error. This will allow
future functionality for errors to be added to the StreamField itself,
rather than a block, similar to adding errors to a form rather than a
specific field.
This commit is contained in:
Tim Heap 2015-12-22 16:26:58 +11:00 committed by Matt Westcott
parent e0a7a472e6
commit 968676c5bb

View file

@ -107,21 +107,20 @@ class BaseStreamBlock(Block):
return "StreamBlock(%s)" % js_dict(opts)
def render_form(self, value, prefix='', errors=None):
error_dict = {}
if errors:
if len(errors) > 1:
# We rely on ListBlock.clean throwing a single ValidationError with a specially crafted
# 'params' attribute that we can pull apart and distribute to the child blocks
raise TypeError('ListBlock.render_form unexpectedly received multiple errors')
error_list = errors.as_data()[0].params
else:
error_list = None
error_dict = errors.as_data()[0].params
# drop any child values that are an unrecognised block type
valid_children = [child for child in value if child.block_type in self.child_blocks]
list_members_html = [
self.render_list_member(child.block_type, child.value, "%s-%d" % (prefix, i), i,
errors=error_list[i] if error_list else None)
errors=error_dict.get(i))
for (i, child) in enumerate(valid_children)
]
@ -160,18 +159,16 @@ class BaseStreamBlock(Block):
def clean(self, value):
cleaned_data = []
errors = []
for child in value: # child is a BoundBlock instance
errors = {}
for i, child in enumerate(value): # child is a BoundBlock instance
try:
cleaned_data.append(
(child.block.name, child.block.clean(child.value))
)
except ValidationError as e:
errors.append(ErrorList([e]))
else:
errors.append(None)
errors[i] = ErrorList([e])
if any(errors):
if errors:
# The message here is arbitrary - outputting error messages is delegated to the child blocks,
# which only involves the 'params' list
raise ValidationError('Validation error in StreamBlock', params=errors)