Skip to content

Commit 8b7ea2b

Browse files
anjaniacatusjacobtylerwalls
authored andcommitted
Refs #36913 -- Maintained error message determinism in MultipleChoiceField.validate().
Used Django's OrderedSet datastructure instead of set() in MultipleChoiceField.validate() to prevent submission ordering from being discarded during validation. Thanks to Jacob Walls, JaeHyuck Sa, Jake Howard and Simon Charette for the reviews.
1 parent f6167b8 commit 8b7ea2b

2 files changed

Lines changed: 5 additions & 4 deletions

File tree

django/forms/fields.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
)
4141
from django.utils import formats
4242
from django.utils.choices import normalize_choices
43+
from django.utils.datastructures import OrderedSet
4344
from django.utils.dateparse import parse_datetime, parse_duration
4445
from django.utils.duration import duration_string
4546
from django.utils.ipv6 import MAX_IPV6_ADDRESS_LENGTH, clean_ipv6_address
@@ -965,8 +966,8 @@ def validate(self, value):
965966
if self.required and not value:
966967
raise ValidationError(self.error_messages["required"], code="required")
967968
# Validate that each value in the value list is in self.choices.
968-
# Use set() to avoid redundant validation.
969-
for val in set(value):
969+
# Avoid redundant validation, and keep elements ordered.
970+
for val in OrderedSet(value):
970971
if not self.valid_value(val):
971972
raise ValidationError(
972973
self.error_messages["invalid_choice"],

tests/forms_tests/field_tests/test_multiplechoicefield.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,5 +91,5 @@ def test_validate_duplicated_values(self):
9191

9292
def test_validate_duplicated_invalid_values(self):
9393
f = MultipleChoiceField(choices=[("1", "one"), ("2", "Two")])
94-
with self.assertRaises(ValidationError):
95-
f.validate(["1", "1", "invalid", "invalid"])
94+
with self.assertRaisesMessage(ValidationError, "invalid-one"):
95+
f.validate(["invalid-one", "invalid-one", "invalid-two"])

0 commit comments

Comments
 (0)