From 50d168f280059c9636ea5d0999765e9f55c63c83 Mon Sep 17 00:00:00 2001 From: Matt Westcott Date: Wed, 13 Jan 2021 16:32:19 +0000 Subject: [PATCH] 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. --- wagtail/core/blocks/struct_block.py | 8 +++++++- wagtail/core/tests/test_blocks.py | 9 +++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/wagtail/core/blocks/struct_block.py b/wagtail/core/blocks/struct_block.py index 24dfa7a9cf..1104980c5f 100644 --- a/wagtail/core/blocks/struct_block.py +++ b/wagtail/core/blocks/struct_block.py @@ -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([ diff --git a/wagtail/core/tests/test_blocks.py b/wagtail/core/tests/test_blocks.py index e1c998468b..e0614da997 100644 --- a/wagtail/core/tests/test_blocks.py +++ b/wagtail/core/tests/test_blocks.py @@ -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()