mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-07-15 18:52:27 +03:00
Merge 40465d95c5
into 2ae8c117da
This commit is contained in:
commit
72202a7386
|
@ -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):
|
||||||
|
|
|
@ -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):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -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:
|
||||||
|
|
Loading…
Reference in New Issue
Block a user