Ensure StructBlock.get_default properly reflects child block defaults

StructBlock previously handled default values 'lazily' at render time, setting meta.default to fall back to an empty dict and calling the child block's get_default on missing items. We can't do this with client-side rendering because get_default isn't available on the client-side block definition (and adding it to the client-side block API would introduce unnecessary bloat). Instead, we fix StructBlock.get_default to correctly pick up the defaults from its child blocks, so that anything that makes use of StructBlock.get_default (e.g. a containing ListBlock / StreamBlock that needs to create StructBlock children on the fly) will have the full accurate data to hand.
pull/6931/head
Matt Westcott 2021-01-13 16:32:19 +00:00
rodzic cf35306e64
commit 50d168f280
2 zmienionych plików z 16 dodań i 1 usunięć

Wyświetl plik

@ -54,7 +54,13 @@ class BaseStructBlock(Block):
rather than a StructValue; for consistency, we need to convert it to a StructValue
for StructBlock to work with
"""
return self._to_struct_value(self.meta.default.items())
return self._to_struct_value([
(
name,
self.meta.default[name] if name in self.meta.default else block.get_default()
)
for name, block in self.child_blocks.items()
])
def value_from_datadict(self, data, files, prefix):
return self._to_struct_value([

Wyświetl plik

@ -1611,6 +1611,15 @@ class TestStructBlock(SimpleTestCase):
html
)
def test_get_default(self):
class LinkBlock(blocks.StructBlock):
title = blocks.CharBlock(default="Torchbox")
link = blocks.URLBlock(default="http://www.torchbox.com")
block = LinkBlock()
default_val = block.get_default()
self.assertEqual(default_val.get('title'), 'Torchbox')
def test_render_form_with_help_text(self):
class LinkBlock(blocks.StructBlock):
title = blocks.CharBlock()