Skip to content

Add a compatibility setting for ListSerializer error formats - #10027

Open
Kub-AT wants to merge 2 commits into
encode:mainfrom
Kub-AT:listserializer-error-format-compatibility
Open

Add a compatibility setting for ListSerializer error formats#10027
Kub-AT wants to merge 2 commits into
encode:mainfrom
Kub-AT:listserializer-error-format-compatibility

Conversation

@Kub-AT

@Kub-AT Kub-AT commented Aug 29, 2026

Copy link
Copy Markdown

Description

Follow-up to #9837 and #10018.

This restores the old ListSerializer error format by default for 3.18.1 and adds LIST_SERIALIZER_ERRORS_AS_DICT for projects that want the dictionary format introduced in 3.18.0.

The dictionary format is planned to become the default in 3.19, with the old format removed in 3.20.

ret.append(validated)

if errors:
if not api_settings.LIST_SERIALIZER_ERRORS_AS_DICT:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd say to move this logic to a separate in-line method that you could decorate with @deprecated instead, so you don't have to create a new class for it and then have to import it in a lot of places (which can be easy to forget or overlook).

Something like this, maybe?

@deprecated('''The list-based error format for `ListSerializer` is 
               deprecated and will be removed in DRF 3.20. Set
               REST_FRAMEWORK["LIST_SERIALIZER_ERRORS_AS_DICT"] to
               True to use the dictionary-based error format.''', stacklevel=4)
def __legacy_serialize_errors(self, errors, data): list:
    return [errors.get(index, {}) for index in range(len(data))]

def __validate_elements(self, data): tuple[list, dict]:
    ret: list = []
    errors: dict = {}
    for index, item in enumerate(data):
        try:
            validated = self.run_child_validation(item)
        except ValidationError as exc:
            errors[index] = exc.detail
        else:
            ret.append(validated)
     return ret, errors

errors: dict | list = None

ret, errors = __validate_elements(data)

if errors:
    if not api_settings.LIST_SERIALIZER_ERRORS_AS_DICT:
        errors = __legacy_serialize_errors(errors, data)
    raise ValidationError(errors)
return ret

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warnings.deprecated was added in Python 3.13, while DRF still supports Python 3.10+

@auvipy
auvipy requested a lite review from Copilot August 30, 2026 16:57
@auvipy
auvipy self-requested a review August 30, 2026 16:59

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a REST framework setting to control the ListSerializer (many=True) per-item validation error format, restoring the legacy list-based structure as the default while allowing opt-in to the newer dict-based format.

Changes:

  • Introduces REST_FRAMEWORK['LIST_SERIALIZER_ERRORS_AS_DICT'] (default False) and updates ListSerializer.to_internal_value() to emit legacy list-form errors (with a deprecation warning) unless the dict format is enabled.
  • Updates and expands serializer list-related tests to cover both formats and warning behavior.
  • Documents the new setting and the deprecation/transition plan in the settings and serializers guides.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
tests/test_serializer.py Adjusts a regression test to expect the new deprecation warning alongside the raised validation error.
tests/test_serializer_lists.py Adds coverage for default legacy list errors, opt-in dict errors, and explicit legacy setting behavior.
tests/test_serializer_bulk_update.py Updates expected bulk many=True error shapes to match the restored legacy list format and asserts warnings.
rest_framework/settings.py Adds the new LIST_SERIALIZER_ERRORS_AS_DICT default setting.
rest_framework/serializers.py Implements conditional legacy-vs-dict error formatting and emits a deprecation warning for the legacy default.
rest_framework/init.py Adds RemovedInDRF320Warning warning class used for the deprecation signal.
docs/api-guide/settings.md Documents the new LIST_SERIALIZER_ERRORS_AS_DICT setting and its behavior.
docs/api-guide/serializers.md Updates serializer error-format documentation to note deprecation and explain enabling dict-based errors.

馃挕 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread rest_framework/serializers.py Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

4 participants