This commit is contained in:
fbozhang 2025-07-07 16:20:56 +04:00 committed by GitHub
commit 72202a7386
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 37 additions and 12 deletions

View File

@ -1469,17 +1469,17 @@ class MultipleChoiceField(ChoiceField):
if not self.allow_empty and len(data) == 0: if not self.allow_empty and len(data) == 0:
self.fail('empty') self.fail('empty')
return { # Arguments for super() are needed because of scoping inside
# Arguments for super() are needed because of scoping inside # comprehensions.
# comprehensions. return list(dict.fromkeys([
super(MultipleChoiceField, self).to_internal_value(item) super(MultipleChoiceField, self).to_internal_value(item)
for item in data for item in data
} ]))
def to_representation(self, value): def to_representation(self, value):
return { return list(dict.fromkeys([
self.choice_strings_to_values.get(str(item), item) for item in value self.choice_strings_to_values.get(str(item), item) for item in value
} ]))
class FilePathField(ChoiceField): class FilePathField(ChoiceField):

View File

@ -11,6 +11,8 @@ from zoneinfo import ZoneInfo
import pytest import pytest
from rest_framework.utils import json
try: try:
import pytz import pytz
except ImportError: except ImportError:
@ -2056,16 +2058,18 @@ class TestMultipleChoiceField(FieldValues):
Valid and invalid values for `MultipleChoiceField`. Valid and invalid values for `MultipleChoiceField`.
""" """
valid_inputs = { valid_inputs = {
(): set(), (): list(),
('aircon',): {'aircon'}, ('aircon',): ['aircon'],
('aircon', 'manual'): {'aircon', 'manual'}, ('aircon', 'manual'): ['aircon', 'manual'],
('manual', 'aircon'): ['manual', 'aircon'],
} }
invalid_inputs = { invalid_inputs = {
'abc': ['Expected a list of items but got type "str".'], 'abc': ['Expected a list of items but got type "str".'],
('aircon', 'incorrect'): ['"incorrect" is not a valid choice.'] ('aircon', 'incorrect'): ['"incorrect" is not a valid choice.']
} }
outputs = [ outputs = [
(['aircon', 'manual', 'incorrect'], {'aircon', 'manual', 'incorrect'}) (['aircon', 'manual', 'incorrect'], ['aircon', 'manual', 'incorrect']),
(['manual', 'aircon', 'incorrect'], ['manual', 'aircon', 'incorrect']),
] ]
field = serializers.MultipleChoiceField( field = serializers.MultipleChoiceField(
choices=[ choices=[
@ -2082,6 +2086,27 @@ class TestMultipleChoiceField(FieldValues):
field.partial = True field.partial = True
assert field.get_value(QueryDict('')) == rest_framework.fields.empty assert field.get_value(QueryDict('')) == rest_framework.fields.empty
def test_valid_inputs_is_json_serializable(self):
for input_value, _ in get_items(self.valid_inputs):
validated = self.field.run_validation(input_value)
try:
json.dumps(validated)
except TypeError as e:
pytest.fail(f'Validated output not JSON serializable: {repr(validated)}; Error: {e}')
def test_output_is_json_serializable(self):
for output_value, _ in get_items(self.outputs):
representation = self.field.to_representation(output_value)
try:
json.dumps(representation)
except TypeError as e:
pytest.fail(
f'to_representation output not JSON serializable: '
f'{repr(representation)}; Error: {e}'
)
class TestEmptyMultipleChoiceField(FieldValues): class TestEmptyMultipleChoiceField(FieldValues):
""" """

View File

@ -199,14 +199,14 @@ class TestNestedSerializerWithList:
serializer = self.Serializer(data=input_data) serializer = self.Serializer(data=input_data)
assert serializer.is_valid() assert serializer.is_valid()
assert serializer.validated_data['nested']['example'] == {1, 2} assert serializer.validated_data['nested']['example'] == [1, 2]
def test_nested_serializer_with_list_multipart(self): def test_nested_serializer_with_list_multipart(self):
input_data = QueryDict('nested.example=1&nested.example=2') input_data = QueryDict('nested.example=1&nested.example=2')
serializer = self.Serializer(data=input_data) serializer = self.Serializer(data=input_data)
assert serializer.is_valid() assert serializer.is_valid()
assert serializer.validated_data['nested']['example'] == {1, 2} assert serializer.validated_data['nested']['example'] == [1, 2]
class TestNotRequiredNestedSerializerWithMany: class TestNotRequiredNestedSerializerWithMany: