From c5c93cba67661fa6fbb922db6261c51a2e5b7c1c Mon Sep 17 00:00:00 2001 From: Yves Serrano Date: Thu, 16 Jun 2022 14:05:48 +0200 Subject: [PATCH] convert DecimalBlock value back to Decimal (#8694) Fixes #4647 --- CHANGELOG.txt | 1 + docs/releases/4.0.md | 1 + wagtail/blocks/field_block.py | 4 ++++ wagtail/tests/test_blocks.py | 18 ++++++++++++++++++ 4 files changed, 24 insertions(+) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 4848e60e38..3182b53da7 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -57,6 +57,7 @@ Changelog * Fix: Prevent error on sending notifications for the legacy moderation process when no user was specified (Yves Serrano) * Fix: Ensure `aria-label` is not set on locale selection dropdown within page chooser modal as it was a duplicate of the button contents (LB (Ben Johnston)) * Fix: Revise the `ModelAdmin` title column behaviour to only link to 'edit' if the user has the correct permissions, fallback to the 'inspect' view or a non-clickable title if needed (Stefan Hammer) + * Fix: Ensure that `DecimalBlock` preserves the `Decimal` type when retrieving from the database (Yves Serrano) 3.0.1 (16.06.2022) diff --git a/docs/releases/4.0.md b/docs/releases/4.0.md index 5b9572ef12..6c1919bb66 100644 --- a/docs/releases/4.0.md +++ b/docs/releases/4.0.md @@ -70,6 +70,7 @@ When using a queryset to render a list of images, you can now use the ``prefetch * Prevent error on sending notifications for the legacy moderation process when no user was specified (Yves Serrano) * Ensure `aria-label` is not set on locale selection dropdown within page chooser modal as it was a duplicate of the button contents (LB (Ben Johnston)) * Revise the `ModelAdmin` title column behaviour to only link to 'edit' if the user has the correct permissions, fallback to the 'inspect' view or a non-clickable title if needed (Stefan Hammer) + * Ensure that `DecimalBlock` preserves the `Decimal` type when retrieving from the database (Yves Serrano) ## Upgrade considerations diff --git a/wagtail/blocks/field_block.py b/wagtail/blocks/field_block.py index a3af86f1ea..ee9e7b4e90 100644 --- a/wagtail/blocks/field_block.py +++ b/wagtail/blocks/field_block.py @@ -1,4 +1,5 @@ import datetime +from decimal import Decimal from django import forms from django.db.models.fields import BLANK_CHOICE_DASH @@ -245,6 +246,9 @@ class DecimalBlock(FieldBlock): ) super().__init__(*args, **kwargs) + def to_python(self, value): + return Decimal(value) + class Meta: icon = "plus-inverse" diff --git a/wagtail/tests/test_blocks.py b/wagtail/tests/test_blocks.py index c05da7007d..9808f97451 100644 --- a/wagtail/tests/test_blocks.py +++ b/wagtail/tests/test_blocks.py @@ -8,6 +8,7 @@ from decimal import Decimal # non-standard import name for gettext_lazy, to prevent strings from being picked up for translation from django import forms from django.core.exceptions import ValidationError +from django.core.serializers.json import DjangoJSONEncoder from django.forms.utils import ErrorList from django.template.loader import render_to_string from django.test import SimpleTestCase, TestCase @@ -411,6 +412,13 @@ class TestDecimalBlock(TestCase): block_val = block.value_from_form(Decimal("1.63")) self.assertEqual(type(block_val), Decimal) + def test_type_to_python(self): + block = blocks.DecimalBlock() + block_val = block.to_python( + "1.63" + ) # decimals get saved as string in JSON field + self.assertEqual(type(block_val), Decimal) + def test_render(self): block = blocks.DecimalBlock() test_val = Decimal(1.63) @@ -446,6 +454,16 @@ class TestDecimalBlock(TestCase): with self.assertRaises(ValidationError): block.clean("3.0") + def test_round_trip_to_db_preserves_type(self): + block = blocks.DecimalBlock() + original_value = Decimal(1.63) + db_value = json.dumps( + block.get_prep_value(original_value), cls=DjangoJSONEncoder + ) + restored_value = block.to_python(json.loads(db_value)) + self.assertEqual(type(restored_value), Decimal) + self.assertEqual(original_value, restored_value) + class TestRegexBlock(TestCase): def test_render(self):