Add a compatibility setting for ListSerializer error formats - #10027
Add a compatibility setting for ListSerializer error formats#10027Kub-AT wants to merge 2 commits into
Conversation
| ret.append(validated) | ||
|
|
||
| if errors: | ||
| if not api_settings.LIST_SERIALIZER_ERRORS_AS_DICT: |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
warnings.deprecated was added in Python 3.13, while DRF still supports Python 3.10+
There was a problem hiding this comment.
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'](defaultFalse) and updatesListSerializer.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.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Description
Follow-up to #9837 and #10018.
This restores the old
ListSerializererror format by default for 3.18.1 and addsLIST_SERIALIZER_ERRORS_AS_DICTfor 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.