From f915a69a93cf1413dfc130a426cb39173b1150e1 Mon Sep 17 00:00:00 2001 From: jacobtoppm Date: Tue, 28 Jul 2020 17:03:39 +0100 Subject: [PATCH] Compare StreamField blocks by serialised value when checking has_changed for a form, preventing form.has_changed from always returning True for pages with StreamFields --- wagtail/core/blocks/base.py | 3 +++ wagtail/core/tests/test_blocks.py | 17 +++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/wagtail/core/blocks/base.py b/wagtail/core/blocks/base.py index 202039d8d8..ba56b686ca 100644 --- a/wagtail/core/blocks/base.py +++ b/wagtail/core/blocks/base.py @@ -542,6 +542,9 @@ class BlockField(forms.Field): def clean(self, value): return self.block.clean(value) + def has_changed(self, initial_value, data_value): + return self.block.get_prep_value(initial_value) != self.block.get_prep_value(data_value) + DECONSTRUCT_ALIASES = { Block: 'wagtail.core.blocks.Block', diff --git a/wagtail/core/tests/test_blocks.py b/wagtail/core/tests/test_blocks.py index e3e696a28e..0dcf9328ec 100644 --- a/wagtail/core/tests/test_blocks.py +++ b/wagtail/core/tests/test_blocks.py @@ -2417,6 +2417,23 @@ class TestStreamBlock(WagtailTestUtils, SimpleTestCase): self.assertEqual(list(block.child_blocks.keys()), ['heading', 'paragraph', 'intro', 'by_line']) + def test_field_has_changed(self): + block = blocks.StreamBlock([('paragraph', blocks.CharBlock())]) + initial_value = blocks.StreamValue(block, [('paragraph', 'test')]) + initial_value[0].id = 'a' + + data_value = blocks.StreamValue(block, [('paragraph', 'test')]) + data_value[0].id = 'a' + + # identical ids and content, so has_changed should return False + self.assertFalse(blocks.BlockField(block).has_changed(initial_value, data_value)) + + changed_data_value = blocks.StreamValue(block, [('paragraph', 'not a test')]) + changed_data_value[0].id = 'a' + + # identical ids but changed content, so has_changed should return True + self.assertTrue(blocks.BlockField(block).has_changed(initial_value, changed_data_value)) + def test_required_raises_an_exception_if_empty(self): block = blocks.StreamBlock([('paragraph', blocks.CharBlock())], required=True) value = blocks.StreamValue(block, [])