Fixed #30583 -- Fixed handling JSONFields in XML serializer.
Co-authored-by: Chason Chaffin <chason@gmail.com>
This commit is contained in:
parent
82da72b748
commit
47651eadb8
|
@ -1,7 +1,7 @@
|
|||
"""
|
||||
XML serializer.
|
||||
"""
|
||||
|
||||
import json
|
||||
from xml.dom import pulldom
|
||||
from xml.sax import handler
|
||||
from xml.sax.expatreader import ExpatParser as _ExpatParser
|
||||
|
@ -75,8 +75,13 @@ class Serializer(base.Serializer):
|
|||
|
||||
# Get a "string version" of the object's data.
|
||||
if getattr(obj, field.name) is not None:
|
||||
value = field.value_to_string(obj)
|
||||
if field.get_internal_type() == 'JSONField':
|
||||
# Dump value since JSONField.value_to_string() doesn't output
|
||||
# strings.
|
||||
value = json.dumps(value, cls=field.encoder)
|
||||
try:
|
||||
self.xml.characters(field.value_to_string(obj))
|
||||
self.xml.characters(value)
|
||||
except UnserializableContentError:
|
||||
raise ValueError("%s.%s (pk:%s) contains unserializable characters" % (
|
||||
obj.__class__.__name__, field.name, obj.pk))
|
||||
|
@ -232,6 +237,9 @@ class Deserializer(base.Deserializer):
|
|||
value = None
|
||||
else:
|
||||
value = field.to_python(getInnerText(field_node).strip())
|
||||
# Load value since JSONField.to_python() outputs strings.
|
||||
if field.get_internal_type() == 'JSONField':
|
||||
value = json.loads(value, cls=field.decoder)
|
||||
data[field.name] = value
|
||||
|
||||
obj = base.build_instance(Model, data, self.db)
|
||||
|
|
|
@ -149,6 +149,21 @@ class TestSerialization(SimpleTestCase):
|
|||
)[0].object
|
||||
self.assertEqual(instance.value, value)
|
||||
|
||||
def test_xml_serialization(self):
|
||||
test_xml_data = (
|
||||
'<django-objects version="1.0">'
|
||||
'<object model="model_fields.nullablejsonmodel">'
|
||||
'<field name="value" type="JSONField">%s'
|
||||
'</field></object></django-objects>'
|
||||
)
|
||||
for value, serialized in self.test_values:
|
||||
with self.subTest(value=value):
|
||||
instance = NullableJSONModel(value=value)
|
||||
data = serializers.serialize('xml', [instance], fields=['value'])
|
||||
self.assertXMLEqual(data, test_xml_data % serialized)
|
||||
new_instance = list(serializers.deserialize('xml', data))[0].object
|
||||
self.assertEqual(new_instance.value, instance.value)
|
||||
|
||||
|
||||
@skipUnlessDBFeature('supports_json_field')
|
||||
class TestSaveLoad(TestCase):
|
||||
|
|
Loading…
Reference in New Issue