diff --git a/rest_framework/fields.py b/rest_framework/fields.py index 89c0a714c6..d5d828c39c 100644 --- a/rest_framework/fields.py +++ b/rest_framework/fields.py @@ -1469,17 +1469,17 @@ def to_internal_value(self, data): if not self.allow_empty and len(data) == 0: self.fail('empty') - return { - # Arguments for super() are needed because of scoping inside - # comprehensions. + # Arguments for super() are needed because of scoping inside + # comprehensions. + return list(dict.fromkeys([ super(MultipleChoiceField, self).to_internal_value(item) for item in data - } + ])) def to_representation(self, value): - return { + return list(dict.fromkeys([ self.choice_strings_to_values.get(str(item), item) for item in value - } + ])) class FilePathField(ChoiceField): diff --git a/tests/test_fields.py b/tests/test_fields.py index d574b07ebc..0b6f4945cf 100644 --- a/tests/test_fields.py +++ b/tests/test_fields.py @@ -11,6 +11,8 @@ import pytest +from rest_framework.utils import json + try: import pytz except ImportError: @@ -2056,16 +2058,18 @@ class TestMultipleChoiceField(FieldValues): Valid and invalid values for `MultipleChoiceField`. """ valid_inputs = { - (): set(), - ('aircon',): {'aircon'}, - ('aircon', 'manual'): {'aircon', 'manual'}, + (): list(), + ('aircon',): ['aircon'], + ('aircon', 'manual'): ['aircon', 'manual'], + ('manual', 'aircon'): ['manual', 'aircon'], } invalid_inputs = { 'abc': ['Expected a list of items but got type "str".'], ('aircon', 'incorrect'): ['"incorrect" is not a valid choice.'] } outputs = [ - (['aircon', 'manual', 'incorrect'], {'aircon', 'manual', 'incorrect'}) + (['aircon', 'manual', 'incorrect'], ['aircon', 'manual', 'incorrect']), + (['manual', 'aircon', 'incorrect'], ['manual', 'aircon', 'incorrect']), ] field = serializers.MultipleChoiceField( choices=[ @@ -2082,6 +2086,27 @@ def test_against_partial_and_full_updates(self): field.partial = True 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): """ diff --git a/tests/test_serializer_nested.py b/tests/test_serializer_nested.py index b7195494c4..4a71dcbcce 100644 --- a/tests/test_serializer_nested.py +++ b/tests/test_serializer_nested.py @@ -199,14 +199,14 @@ def test_nested_serializer_with_list_json(self): serializer = self.Serializer(data=input_data) 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): input_data = QueryDict('nested.example=1&nested.example=2') serializer = self.Serializer(data=input_data) assert serializer.is_valid() - assert serializer.validated_data['nested']['example'] == {1, 2} + assert serializer.validated_data['nested']['example'] == [1, 2] class TestNotRequiredNestedSerializerWithMany: pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy