From 31a18e12f00a3c41ad70247bab824df10a202da9 Mon Sep 17 00:00:00 2001 From: "Jens W. Klein" Date: Mon, 6 Mar 2023 10:08:10 +0100 Subject: [PATCH] Support Decimal fields while deserializing. (#903) Support Decimal fields while de-serializing and add section to docs. Co-authored-by: David Glick --- docs/source/usage/serialization.md | 18 +++++++++++++++--- news/903.bugfix | 2 ++ src/plone/restapi/deserializer/configure.zcml | 1 + src/plone/restapi/deserializer/dxfields.py | 12 ++++++++++++ src/plone/restapi/tests/dxtypes.py | 3 --- .../restapi/tests/test_dxfield_deserializer.py | 10 ++++++++++ .../restapi/tests/test_dxfield_serializer.py | 8 ++++---- 7 files changed, 44 insertions(+), 10 deletions(-) create mode 100644 news/903.bugfix diff --git a/docs/source/usage/serialization.md b/docs/source/usage/serialization.md index aebe2b0a3d..e77b7a5a0a 100644 --- a/docs/source/usage/serialization.md +++ b/docs/source/usage/serialization.md @@ -31,6 +31,16 @@ Since JSON does not have native support for dates and times, the Python and Zope | `DateTime("2015/11/23 19:45:55")` | `"2015-11-23T19:45:55"` | +## Decimal Type + +The [Python Decimal type](https://docs.python.org/3/library/decimal.html) supports correctly rounded decimal floating point arithmetic. +To keep the precision, serializing the value to JSON results in a string. + +| Python | JSON | +| ------------------------------------ | ----------------------- | +| `Decimal("3.14159265359")` | `"3.14159265359"` | + + ## RichText fields RichText fields will be serialized as follows: @@ -38,9 +48,11 @@ RichText fields will be serialized as follows: A `RichTextValue` such as the following: ```python -RichTextValue(u'

Hallöchen

', - mimeType='text/html', - outputMimeType='text/html') +RichTextValue( + "

Hallöchen

", + mimeType="text/html", + outputMimeType="text/html", +) ``` …will be serialized to: diff --git a/news/903.bugfix b/news/903.bugfix new file mode 100644 index 0000000000..3a0b13b664 --- /dev/null +++ b/news/903.bugfix @@ -0,0 +1,2 @@ +Fix missing `Decimal` field deserializer. +[jensens] diff --git a/src/plone/restapi/deserializer/configure.zcml b/src/plone/restapi/deserializer/configure.zcml index e6a8bea9ae..f7b4d5c5ac 100644 --- a/src/plone/restapi/deserializer/configure.zcml +++ b/src/plone/restapi/deserializer/configure.zcml @@ -18,6 +18,7 @@ + ") self.assertEqual(1.0, value) + def test_float_deserialization_returns_decimal(self): + value = self.deserialize("test_decimal_field", 1.111) + self.assertTrue(isinstance(value, Decimal), "Not a ") + # a float from JSON to decimal can not work properly, so you would get + # real floating point precision only + self.assertEqual( + Decimal("1.1109999999999999875655021241982467472553253173828125"), + value, + ) + def test_frozenset_deserialization_returns_frozenset(self): value = self.deserialize("test_frozenset_field", ["foo", "bar"]) self.assertTrue(isinstance(value, frozenset), "Not a ") diff --git a/src/plone/restapi/tests/test_dxfield_serializer.py b/src/plone/restapi/tests/test_dxfield_serializer.py index eb1e83c154..6c386ece68 100644 --- a/src/plone/restapi/tests/test_dxfield_serializer.py +++ b/src/plone/restapi/tests/test_dxfield_serializer.py @@ -104,10 +104,10 @@ def test_datetime_field_serialization_returns_unicode(self): self.assertTrue(isinstance(value, str), "Not an ") self.assertEqual("2015-06-20T13:22:04", value) - def test_decimal_field_serialization_returns_unicode(self): - value = self.serialize("test_decimal_field", Decimal("1.1")) - self.assertTrue(isinstance(value, str), "Not an ") - self.assertEqual("1.1", value) + def test_decimal_field_serialization_returns_str(self): + value = self.serialize("test_decimal_field", Decimal("1.111")) + self.assertTrue(isinstance(value, str), "Not an ") + self.assertEqual("1.111", value) def test_dict_field_serialization_returns_dict(self): value = self.serialize(