diff options
| author | Youngkwang Yang <me@youngkwang.dev> | 2025-12-18 13:49:13 +0900 |
|---|---|---|
| committer | Jacob Walls <jacobtylerwalls@gmail.com> | 2025-12-22 14:21:01 -0500 |
| commit | 95394443bff2cd6c5cb47c752422fe1f391bb43d (patch) | |
| tree | 9569a6075cf7152be47c5163c952fb76c8ce58ac /django/core | |
| parent | 6ee8e9d56c17eb0014e73189950a9e8de2a8ec0e (diff) | |
Fixed #36786 -- Fixed XML serialization of None values in natural keys.
None values in natural keys were incorrectly serialized as the string
"None", causing deserialization to fail for fields like UUIDField.
Diffstat (limited to 'django/core')
| -rw-r--r-- | django/core/serializers/xml_serializer.py | 42 |
1 files changed, 33 insertions, 9 deletions
diff --git a/django/core/serializers/xml_serializer.py b/django/core/serializers/xml_serializer.py index a9fe3cf01d..d43865c257 100644 --- a/django/core/serializers/xml_serializer.py +++ b/django/core/serializers/xml_serializer.py @@ -134,7 +134,10 @@ class Serializer(base.Serializer): # Iterable natural keys are rolled out as subelements for key_value in natural_key_value: self.xml.startElement("natural", {}) - self.xml.characters(str(key_value)) + if key_value is None: + self.xml.addQuickElement("None") + else: + self.xml.characters(str(key_value)) self.xml.endElement("natural") else: self.xml.characters(str(related_att)) @@ -160,7 +163,10 @@ class Serializer(base.Serializer): self.xml.startElement("object", {}) for key_value in natural: self.xml.startElement("natural", {}) - self.xml.characters(str(key_value)) + if key_value is None: + self.xml.addQuickElement("None") + else: + self.xml.characters(str(key_value)) self.xml.endElement("natural") self.xml.endElement("object") else: @@ -279,7 +285,11 @@ class Deserializer(base.Deserializer): if value == base.DEFER_FIELD: deferred_fields[field] = [ [ - getInnerText(nat_node).strip() + ( + None + if nat_node.getElementsByTagName("None") + else getInnerText(nat_node).strip() + ) for nat_node in obj_node.getElementsByTagName("natural") ] for obj_node in field_node.getElementsByTagName("object") @@ -292,7 +302,11 @@ class Deserializer(base.Deserializer): value = self._handle_fk_field_node(field_node, field) if value == base.DEFER_FIELD: deferred_fields[field] = [ - getInnerText(k).strip() + ( + None + if k.getElementsByTagName("None") + else getInnerText(k).strip() + ) for k in field_node.getElementsByTagName("natural") ] else: @@ -317,16 +331,21 @@ class Deserializer(base.Deserializer): Handle a <field> node for a ForeignKey """ # Check if there is a child node named 'None', returning None if so. - if node.getElementsByTagName("None"): + natural_keys = node.getElementsByTagName("natural") + if node.getElementsByTagName("None") and not natural_keys: return None else: model = field.remote_field.model if hasattr(model._default_manager, "get_by_natural_key"): - keys = node.getElementsByTagName("natural") - if keys: + if natural_keys: # If there are 'natural' subelements, it must be a natural # key - field_value = [getInnerText(k).strip() for k in keys] + field_value = [] + for k in natural_keys: + if k.getElementsByTagName("None"): + field_value.append(None) + else: + field_value.append(getInnerText(k).strip()) try: obj = model._default_manager.db_manager( self.db @@ -367,7 +386,12 @@ class Deserializer(base.Deserializer): if keys: # If there are 'natural' subelements, it must be a natural # key - field_value = [getInnerText(k).strip() for k in keys] + field_value = [] + for k in keys: + if k.getElementsByTagName("None"): + field_value.append(None) + else: + field_value.append(getInnerText(k).strip()) obj_pk = ( default_manager.db_manager(self.db) .get_by_natural_key(*field_value) |
