Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion rest_framework/utils/serializer_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,14 @@ def __iter__(self):
def __getitem__(self, key):
field = self.fields[key]
value = self.value.get(key) if self.value else None
error = self.errors.get(key) if isinstance(self.errors, dict) else None

if isinstance(self.errors, dict):
error = self.errors.get(key)
elif isinstance(self.errors, list):
error = {} # normalize list to empty dict for nested children
else:
error = None

if hasattr(field, 'fields'):
return NestedBoundField(field, value, error, prefix=self.name + '.')
elif getattr(field, '_is_jsonfield', False):
Expand Down
23 changes: 23 additions & 0 deletions tests/test_bound_fields.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from django.http import QueryDict

from rest_framework import serializers
from rest_framework.exceptions import ValidationError


class TestSimpleBoundField:
Expand Down Expand Up @@ -211,6 +212,28 @@ class ExampleSerializer(serializers.Serializer):
rendered_packed = ''.join(rendered.split())
assert rendered_packed == expected_packed

def test_child_bound_field_after_parent_validation_error(self):
class ChildSerializer(serializers.Serializer):
value = serializers.CharField()

class ParentSerializer(serializers.Serializer):
nested = ChildSerializer()

def validate_nested(self, nested):
# Raise parent-level (non-field) validation error
raise ValidationError(["parent-level nested error"])

serializer = ParentSerializer(data={"nested": {"value": "ignored"}})
assert not serializer.is_valid()

# Parent-level error is a list (current problematic case)
assert serializer.errors["nested"] == ["parent-level nested error"]
parent_bound = serializer["nested"]
child_bound = parent_bound["value"]
assert isinstance(child_bound.errors, dict)
assert child_bound.value == "ignored"
assert child_bound.name == "nested.value"


class TestJSONBoundField:
def test_as_form_fields(self):
Expand Down
Loading