Skip to content

Commit 7ef2f1d

Browse files
committed
Fix child instance resolution in ListSerializer
1 parent 395cebe commit 7ef2f1d

File tree

2 files changed

+32
-6
lines changed

2 files changed

+32
-6
lines changed

rest_framework/serializers.py

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -662,14 +662,40 @@ def run_child_validation(self, data):
662662
if model is not None:
663663
pk_name = model._meta.pk.name
664664

665+
obj_id = None
665666
if pk_name:
666-
obj_id = data.get(pk_name, data.get("pk", data.get("id")))
667-
if obj_id is not None:
668-
for obj in self.instance:
669-
if hasattr(obj, pk_name) and getattr(obj, pk_name) == obj_id:
670-
child_instance = obj
667+
for field_name, field in self.child.fields.items():
668+
if getattr(field, "source", None) == pk_name:
669+
obj_id = data.get(field_name)
670+
if obj_id is not None:
671671
break
672672

673+
if obj_id is None:
674+
obj_id = data.get(pk_name) or data.get("pk") or data.get("id")
675+
676+
resolved_instance = None
677+
678+
if obj_id is not None and pk_name:
679+
try:
680+
obj_id = model._meta.pk.to_python(obj_id)
681+
except Exception:
682+
pass
683+
684+
if not hasattr(self, "_instance_index"):
685+
self._instance_index = {
686+
getattr(obj, pk_name): obj for obj in self.instance
687+
}
688+
689+
resolved_instance = self._instance_index.get(obj_id)
690+
691+
if resolved_instance is None:
692+
if model is not None and self.context.get("allow_create", True):
693+
resolved_instance = model()
694+
else:
695+
resolved_instance = child_instance
696+
697+
child_instance = resolved_instance
698+
673699
self.child.instance = child_instance
674700
self.child.initial_data = data
675701
return self.child.run_validation(data)

tests/test_serializer_lists.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -860,7 +860,7 @@ def test_uuid_validate_many(self):
860860

861861
input_data = [
862862
{
863-
"uuid": "t3308237e-18d8-4074-9d05-79cc0fdb5bb3",
863+
"uuid": "c20f2f31-65a3-451f-ae7d-e939b7d9f84b",
864864
"name": "bar",
865865
},
866866
]

0 commit comments

Comments
 (0)