Map QueryDict to dict inside get_non_list_response()

This commit is contained in:
Jeremy Stretch 2026-08-12 11:25:29 -04:00
parent b9f13c6c75
commit 42df031c06
2 changed files with 16 additions and 7 deletions

View File

@ -493,6 +493,18 @@ class SiteTestCase(APIViewTestCases.APIViewTestCase):
# A non-list body is described by its type, so that the client can see what was sent
self.assertEqual(response.data['detail'], 'Expected a list of objects, but got dict.')
# A multipart body reaches the bulk action as a QueryDict, which must be reported as the
# dict the client submitted rather than by that internal class name
response = self.client.patch(
self._get_list_url(), {'id': site.pk, 'description': 'x'}, format='multipart', **self.header
)
self.assertHttpStatus(response, status.HTTP_400_BAD_REQUEST)
self.assertEqual(response.data['detail'], 'Expected a list of objects, but got dict.')
site.refresh_from_db()
self.assertEqual(site.description, '')
def test_bulk_write_objects_empty_body(self):
"""
Address a list endpoint with no body at all. An absent body reaches the bulk actions as an

View File

@ -93,16 +93,13 @@ def get_non_list_response(data):
if isinstance(data, list):
return None
# A request with no body at all arrives here as an empty dict, so reporting its type would tell
# the client only that it "got dict" -- unhelpful for what is the likeliest way to reach this
# point: a DELETE addressed to a list endpoint with nothing in the body. An explicitly submitted
# empty object is indistinguishable at this stage, and wants the same message anyway.
if data is None or data == {} or data == '':
detail = _('Expected a list of objects, but no data was submitted.')
else:
detail = _('Expected a list of objects, but got {datatype}.').format(
datatype=type(data).__name__
)
# A multipart body arrives as a QueryDict rather than as a plain dict, so report any mapping
# by the type the client submitted rather than by the class which happens to carry it.
datatype = 'dict' if isinstance(data, dict) else type(data).__name__
detail = _('Expected a list of objects, but got {datatype}.').format(datatype=datatype)
return Response({'detail': detail}, status=status.HTTP_400_BAD_REQUEST)