Skip to content
Open
Changes from all 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
31 changes: 25 additions & 6 deletions rest_framework/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,18 @@ def __new__(cls, name, bases, attrs):


def as_serializer_error(exc):
"""
Coerce validation exceptions into a standardized serialized error format.

This function normalizes both Django's `ValidationError` and REST
framework's `ValidationError` into a dictionary structure compatible
with serializer `.errors`, ensuring all values are represented as
lists of error details.

The returned structure conforms to the serializer error contract:
- Field-specific errors are returned as '{field-name: [errors]}'
- Non-field errors are returned under the 'NON_FIELD_ERRORS_KEY'
"""
assert isinstance(exc, (ValidationError, DjangoValidationError))

if isinstance(exc, DjangoValidationError):
Expand Down Expand Up @@ -815,22 +827,29 @@ def errors(self):

def raise_errors_on_nested_writes(method_name, serializer, validated_data):
"""
Give explicit errors when users attempt to pass writable nested data.
Enforce explicit handling of writable nested and dotted-source fields.

If we don't do this explicitly they'd get a less helpful error when
calling `.save()` on the serializer.
This helper raises clear and actionable errors when a serializer attempts
to perform writable nested updates or creates using the default
`ModelSerializer` behavior.

We don't *automatically* support these sorts of nested writes because
there are too many ambiguities to define a default behavior.
Writable nested relationships and dotted-source fields are intentionally
unsupported by default due to ambiguous persistence semantics. Developers
must either:
- Override the `.create()` / `.update()` methods explicitly, or
- Mark nested serializers as `read_only=True`

This check is invoked internally by default `ModelSerializer.create()`
and `ModelSerializer.update()` implementations.

Eg. Suppose we have a `UserSerializer` with a nested profile. How should
we handle the case of an update, where the `profile` relationship does
not exist? Any of the following might be valid:

* Raise an application error.
* Silently ignore the nested part of the update.
* Automatically create a profile instance.
"""

ModelClass = serializer.Meta.model
model_field_info = model_meta.get_field_info(ModelClass)

Expand Down
Loading