mirror of
https://github.com/wagtail/wagtail.git
synced 2024-12-01 11:41:20 +01:00
implement __setitem__ on StreamValue
This commit is contained in:
parent
603dc650e5
commit
caade5f0de
@ -1,7 +1,7 @@
|
||||
import uuid
|
||||
|
||||
from collections import OrderedDict, defaultdict
|
||||
from collections.abc import Sequence
|
||||
from collections.abc import MutableSequence
|
||||
|
||||
from django import forms
|
||||
from django.core.exceptions import NON_FIELD_ERRORS, ValidationError
|
||||
@ -383,7 +383,7 @@ class StreamBlock(BaseStreamBlock, metaclass=DeclarativeSubBlocksMetaclass):
|
||||
pass
|
||||
|
||||
|
||||
class StreamValue(Sequence):
|
||||
class StreamValue(MutableSequence):
|
||||
"""
|
||||
Custom type used to represent the value of a StreamBlock; behaves as a sequence of BoundBlocks
|
||||
(which keep track of block types in a way that the values alone wouldn't).
|
||||
@ -446,16 +446,27 @@ class StreamValue(Sequence):
|
||||
else:
|
||||
# store native stream data in _bound_blocks; on serialization it will be converted to
|
||||
# a JSON-ish representation via block.get_prep_value.
|
||||
self._bound_blocks = {}
|
||||
for i, item in enumerate(stream_data):
|
||||
try:
|
||||
type_name, value, block_id = item
|
||||
except ValueError:
|
||||
type_name, value = item
|
||||
block_id = None
|
||||
self._bound_blocks = {
|
||||
i: self._construct_stream_child(item)
|
||||
for i, item in enumerate(stream_data)
|
||||
}
|
||||
|
||||
block_def = self.stream_block.child_blocks[type_name]
|
||||
self._bound_blocks[i] = StreamValue.StreamChild(block_def, value, id=block_id)
|
||||
def _construct_stream_child(self, item):
|
||||
"""
|
||||
Create a StreamChild instance from a (type, value, id) or (type, value) tuple,
|
||||
or return item if it's already a StreamChild
|
||||
"""
|
||||
if isinstance(item, StreamValue.StreamChild):
|
||||
return item
|
||||
|
||||
try:
|
||||
type_name, value, block_id = item
|
||||
except ValueError:
|
||||
type_name, value = item
|
||||
block_id = None
|
||||
|
||||
block_def = self.stream_block.child_blocks[type_name]
|
||||
return StreamValue.StreamChild(block_def, value, id=block_id)
|
||||
|
||||
def __getitem__(self, i):
|
||||
if i not in range(0, self._length):
|
||||
@ -467,6 +478,15 @@ class StreamValue(Sequence):
|
||||
|
||||
return self._bound_blocks[i]
|
||||
|
||||
def __setitem__(self, i, item):
|
||||
self._bound_blocks[i] = self._construct_stream_child(item)
|
||||
|
||||
def __delitem__(self, i):
|
||||
raise NotImplementedError
|
||||
|
||||
def insert(self, i, item):
|
||||
raise NotImplementedError
|
||||
|
||||
def _prefetch_blocks(self, type_name):
|
||||
"""
|
||||
Populate _bound_blocks with all items in this stream of type `type_name` that exist in
|
||||
|
@ -3367,6 +3367,40 @@ class TestStreamBlock(WagtailTestUtils, SimpleTestCase):
|
||||
{'type': 'paragraph', 'value': 'earth', 'id': '0002'},
|
||||
])
|
||||
|
||||
def test_set_streamvalue_item(self):
|
||||
class ArticleBlock(blocks.StreamBlock):
|
||||
heading = blocks.CharBlock()
|
||||
paragraph = blocks.CharBlock()
|
||||
|
||||
block = ArticleBlock()
|
||||
stream = block.to_python([
|
||||
{'type': 'heading', 'value': 'hello', 'id': '0001'},
|
||||
{'type': 'paragraph', 'value': 'world', 'id': '0002'},
|
||||
])
|
||||
stream[1] = ('heading', 'goodbye', '0003')
|
||||
raw_data = block.get_prep_value(stream)
|
||||
self.assertEqual(raw_data, [
|
||||
{'type': 'heading', 'value': 'hello', 'id': '0001'},
|
||||
{'type': 'heading', 'value': 'goodbye', 'id': '0003'},
|
||||
])
|
||||
|
||||
@unittest.expectedFailure
|
||||
def test_delete_streamvalue_item(self):
|
||||
class ArticleBlock(blocks.StreamBlock):
|
||||
heading = blocks.CharBlock()
|
||||
paragraph = blocks.CharBlock()
|
||||
|
||||
block = ArticleBlock()
|
||||
stream = block.to_python([
|
||||
{'type': 'heading', 'value': 'hello', 'id': '0001'},
|
||||
{'type': 'paragraph', 'value': 'world', 'id': '0002'},
|
||||
])
|
||||
del stream[0]
|
||||
raw_data = block.get_prep_value(stream)
|
||||
self.assertEqual(raw_data, [
|
||||
{'type': 'paragraph', 'value': 'world', 'id': '0002'},
|
||||
])
|
||||
|
||||
def test_render_with_classname_via_kwarg(self):
|
||||
"""form_classname from kwargs to be used as an additional class when rendering stream block"""
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user