diff --git a/wagtail/blocks/base.py b/wagtail/blocks/base.py index e0128ba9af..c37d359a56 100644 --- a/wagtail/blocks/base.py +++ b/wagtail/blocks/base.py @@ -298,6 +298,10 @@ class Block(metaclass=BaseBlock): return self.normalize(self.meta.preview_value) return self.get_default() + @cached_property + def _has_default(self): + return getattr(self.meta, "default", None) is not None + @cached_property def is_previewable(self): # To prevent showing a broken preview if the block preview has not been @@ -314,7 +318,7 @@ class Block(metaclass=BaseBlock): ) has_preview_value = ( hasattr(self.meta, "preview_value") - or getattr(self.meta, "default", None) is not None + or self._has_default or self.__class__.get_preview_context is not Block.get_preview_context or self.__class__.get_preview_value is not Block.get_preview_value ) diff --git a/wagtail/blocks/list_block.py b/wagtail/blocks/list_block.py index 3fcbdcff9e..c7505e387e 100644 --- a/wagtail/blocks/list_block.py +++ b/wagtail/blocks/list_block.py @@ -147,7 +147,8 @@ class ListBlock(Block): else: self.child_block = child_block - if not hasattr(self.meta, "default"): + self._has_default = hasattr(self.meta, "default") + if not self._has_default: # Default to a list consisting of one empty (i.e. default-valued) child item self.meta.default = [self.child_block.get_default()] diff --git a/wagtail/blocks/stream_block.py b/wagtail/blocks/stream_block.py index a8ab0f7010..6c38789e83 100644 --- a/wagtail/blocks/stream_block.py +++ b/wagtail/blocks/stream_block.py @@ -460,6 +460,10 @@ class BaseStreamBlock(Block): return errors + @cached_property + def _has_default(self): + return self.meta.default is not BaseStreamBlock._meta_class.default + class Meta: # No icon specified here, because that depends on the purpose that the # block is being used for. Feel encouraged to specify an icon in your diff --git a/wagtail/blocks/struct_block.py b/wagtail/blocks/struct_block.py index 05a717cb8c..a4e8f93d23 100644 --- a/wagtail/blocks/struct_block.py +++ b/wagtail/blocks/struct_block.py @@ -382,6 +382,10 @@ class BaseStructBlock(Block): "prefix": prefix, } + @cached_property + def _has_default(self): + return self.meta.default is not BaseStructBlock._meta_class.default + class Meta: default = {} form_classname = "struct-block" diff --git a/wagtail/tests/test_blocks.py b/wagtail/tests/test_blocks.py index 3ef4b6c556..6dc4ee0a5a 100644 --- a/wagtail/tests/test_blocks.py +++ b/wagtail/tests/test_blocks.py @@ -93,6 +93,11 @@ class TestBlock(SimpleTestCase): "specific_template_and_custom_value": [ blocks.Block(preview_template="foo.html", preview_value="bar"), ], + "unset_default_not_none": [ + blocks.ListBlock(blocks.Block()), + blocks.StreamBlock(), + blocks.StructBlock(), + ], } # Test without a global template override @@ -109,6 +114,9 @@ class TestBlock(SimpleTestCase): # Providing both a preview template and value also makes the block # previewable, this is the same as providing a custom template only ("specific_template_and_custom_value", True), + # These blocks define their own unset default value that is not + # `None`, and that value should not make it previewable + ("unset_default_not_none", False), ] for variant, is_previewable in cases: with self.subTest(variant=variant, custom_global_template=False): @@ -134,6 +142,9 @@ class TestBlock(SimpleTestCase): ("custom_value", True), # Unchanged – providing both also makes the block previewable ("specific_template_and_custom_value", True), + # Unchanged – even after providing a global template override, + # these blocks should not be previewable + ("unset_default_not_none", False), ] for variant, is_previewable in cases: with self.subTest(variant=variant, custom_global_template=True):