Skip to content

Commit aec3126

Browse files
committed
updated child validation for ListSerializer
1 parent 1472848 commit aec3126

File tree

3 files changed

+58
-1
lines changed

3 files changed

+58
-1
lines changed

rest_framework/serializers.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -652,6 +652,14 @@ def run_child_validation(self, data):
652652
self.child.initial_data = data
653653
return super().run_child_validation(data)
654654
"""
655+
instance = None
656+
if self.instance is not None:
657+
instance_map = {getattr(obj, 'pk', None): obj for obj in self.instance}
658+
obj_id = data.get('pk') if isinstance(data, dict) else None
659+
instance = instance_map.get(obj_id)
660+
661+
self.child.instance = instance
662+
self.child.initial_data = data
655663
return self.child.run_validation(data)
656664

657665
def to_internal_value(self, data):

tests/models.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,3 +150,8 @@ def __new__(cls, *args, **kwargs):
150150
help_text='OneToOneTarget',
151151
verbose_name='OneToOneTarget',
152152
on_delete=models.CASCADE)
153+
154+
155+
class TestListModel(models.Model):
156+
name = models.CharField(max_length=50)
157+
value = models.IntegerField()

tests/test_serializer_lists.py

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from rest_framework import serializers
66
from rest_framework.exceptions import ErrorDetail
77
from tests.models import (
8-
CustomManagerModel, NullableOneToOneSource, OneToOneTarget
8+
CustomManagerModel, NullableOneToOneSource, OneToOneTarget, TestListModel
99
)
1010

1111

@@ -775,3 +775,47 @@ def test(self):
775775
queryset = NullableOneToOneSource.objects.all()
776776
serializer = self.serializer(queryset, many=True)
777777
assert serializer.data
778+
779+
780+
class TestManyTrueValidationCheck:
781+
"""
782+
Tests ListSerializer validation with many=True for both valid and invalid model data.
783+
"""
784+
785+
@pytest.mark.django_db
786+
def test_run_child_validation_with_many_true(self):
787+
obj1 = TestListModel.objects.create(name="A", value=1)
788+
obj2 = TestListModel.objects.create(name="B", value=2)
789+
790+
class TestListModelSerializer(serializers.ModelSerializer):
791+
class Meta:
792+
model = TestListModel
793+
fields = ["id", "name", "value"]
794+
795+
input_data = [
796+
{"id": obj1.id, "name": "Updated A", "value": 10},
797+
{"id": obj2.id, "name": "Updated B", "value": 20},
798+
]
799+
800+
serializer = TestListModelSerializer([obj1, obj2], data=input_data, many=True)
801+
assert serializer.is_valid(), serializer.errors
802+
803+
serializer = TestListModelSerializer(TestListModel.objects.all(), data=input_data, many=True)
804+
assert serializer.is_valid(), serializer.errors
805+
806+
@pytest.mark.django_db
807+
def test_validation_error_for_invalid_data(self):
808+
obj = TestListModel.objects.create(name="C", value=5)
809+
810+
class TestListModelSerializer(serializers.ModelSerializer):
811+
class Meta:
812+
model = TestListModel
813+
fields = ["id", "name", "value"]
814+
815+
input_data = [
816+
{"id": obj.pk, "name": "", "value": -1},
817+
]
818+
819+
serializer = TestListModelSerializer([obj], data=input_data, many=True)
820+
assert not serializer.is_valid()
821+
assert "name" in serializer.errors[0]

0 commit comments

Comments
 (0)