summaryrefslogtreecommitdiff
path: root/django/core
diff options
context:
space:
mode:
authorYoungkwang Yang <me@youngkwang.dev>2025-12-18 13:49:13 +0900
committerJacob Walls <jacobtylerwalls@gmail.com>2025-12-22 14:21:01 -0500
commit95394443bff2cd6c5cb47c752422fe1f391bb43d (patch)
tree9569a6075cf7152be47c5163c952fb76c8ce58ac /django/core
parent6ee8e9d56c17eb0014e73189950a9e8de2a8ec0e (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.py42
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)