Skip to content

Addresses #7279 : consistent formatting btw list serializers and list field errors#9837

Open
p-r-a-v-i-n wants to merge 7 commits intoencode:mainfrom
p-r-a-v-i-n:fix/7279-listserializer-errors
Open

Addresses #7279 : consistent formatting btw list serializers and list field errors#9837
p-r-a-v-i-n wants to merge 7 commits intoencode:mainfrom
p-r-a-v-i-n:fix/7279-listserializer-errors

Conversation

@p-r-a-v-i-n
Copy link
Copy Markdown
Contributor

@p-r-a-v-i-n p-r-a-v-i-n commented Nov 26, 2025

Fix #7279

This pr changes the formatting of list serializer errors.

  • previously list serializer returing errors in list format.
  • It was adding empty dict ("{}") for every valid item in the list
  • this format was not consistent with the list field error format.
  • this is previous sample format
{
    'list_serializer': [
        {},
        {'num': [ErrorDetail(string='Must be a valid boolean.', code='invalid')]},
        {},
        {'num': [ErrorDetail(string='Must be a valid boolean.', code='invalid')]}
    ],
    
    'list_field': {
        1: [ErrorDetail(string='This dictionary may not be empty.', code='empty')],
        3: [ErrorDetail(string='This dictionary may not be empty.', code='empty')]
    }
}

Changes:

  • returning dict instead of the list bcs :

    • it is easier to handle dict compare to list for clients
    • if there 100 items in which 99 are valid then it would add 99 "{}" in the list.
    • both list field and list serializer errors are consistent.
  • here is the updated sample format

{
    'list_serializer': {
        0: {'num': [ErrorDetail(string='Must be a valid boolean.', code='invalid')]},
        1: {'num': [ErrorDetail(string='Must be a valid boolean.', code='invalid')]}
    },
    
    'list_field': {
        1: [ErrorDetail(string='This dictionary may not be empty.', code='empty')],
        3: [ErrorDetail(string='This dictionary may not be empty.', code='empty')]
    }
}

for clarity I can add more example if needed.

@p-r-a-v-i-n p-r-a-v-i-n marked this pull request as draft November 26, 2025 05:59
@p-r-a-v-i-n p-r-a-v-i-n marked this pull request as ready for review November 26, 2025 06:45
Copy link
Copy Markdown
Member

@browniebroke browniebroke left a comment

Choose a reason for hiding this comment

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

here is the updated sample format

{
    'list_serializer': {
        0: {'num': [ErrorDetail(string='Must be a valid boolean.', code='invalid')]},
        1: {'num': [ErrorDetail(string='Must be a valid boolean.', code='invalid')]}
    },
    
    'list_field': {
        1: [ErrorDetail(string='This dictionary may not be empty.', code='empty')],
        3: [ErrorDetail(string='This dictionary may not be empty.', code='empty')]
    }
}

The top level structure is indeed a dict, but the values of this dict aren't consistent: in the list serializer case, they are dict[str, list[ErrorDetail]] while in the list field they are list[ErrorDetail].

Is that right or am I missing something?

EDIT: I think I got it, ignore this comment

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR changes the error format for ListSerializer to use a dict-based structure (with indices as keys) instead of a list-based structure (with empty dicts for valid items). This improves consistency with how ListField handles errors and makes error handling easier for API clients.

  • Changed error structure from list to dict format for ListSerializer
  • Only invalid item indices are included in error dict (no empty placeholders for valid items)
  • Ensures consistency between ListSerializer and ListField error formats

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
rest_framework/serializers.py Modified to_internal_value to collect errors in a dict keyed by index instead of a list with empty dicts for valid items
tests/test_serializer_lists.py Added comprehensive tests for dict-based error format and consistency between ListSerializer and ListField
tests/test_serializer_bulk_update.py Updated expected error format in tests to use dict structure with indices as keys

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@browniebroke
Copy link
Copy Markdown
Member

Looks good to me as well, but that's probably going to be seen as a breaking change so will need to wait for 3.18 IMO

I suggest we hold off merging for a bit to let us release any potential bug fixes for 3.17.x... What do you think?

@browniebroke browniebroke added this to the 3.18 milestone Apr 10, 2026
@Natgho
Copy link
Copy Markdown
Contributor

Natgho commented Apr 10, 2026

Looks good to me as well, but that's probably going to be seen as a breaking change so will need to wait for 3.18 IMO

I suggest we hold off merging for a bit to let us release any potential bug fixes for 3.17.x... What do you think?

That makes sense, because this situation will cause many of the error tests in projects using DRF to fail.

@p-r-a-v-i-n
Copy link
Copy Markdown
Contributor Author

I'm agreed with @browniebroke . It was there in my mind when we were releasing 3.17. but I missed it. I should have pinged you both about this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ListField validation errors are inconsistent with ListSerializer

5 participants