diff --git a/django/forms/fields.py b/django/forms/fields.py
index bc37701..8c0a061 100644
a
|
b
|
class ChoiceField(Field):
|
782 | 782 | if isinstance(v, (list, tuple)): |
783 | 783 | # This is an optgroup, so look inside the group for options |
784 | 784 | for k2, v2 in v: |
785 | | if value == smart_text(k2): |
| 785 | if value == k2 or force_text(value) == force_text(k2): |
786 | 786 | return True |
787 | 787 | else: |
788 | | if value == smart_text(k): |
| 788 | if value == k or force_text(value) == force_text(k): |
789 | 789 | return True |
790 | 790 | return False |
791 | 791 | |
… |
… |
class TypedChoiceField(ChoiceField):
|
801 | 801 | right type. |
802 | 802 | """ |
803 | 803 | value = super(TypedChoiceField, self).to_python(value) |
804 | | super(TypedChoiceField, self).validate(value) |
805 | 804 | if value == self.empty_value or value in self.empty_values: |
806 | 805 | return self.empty_value |
807 | 806 | try: |
… |
… |
class TypedChoiceField(ChoiceField):
|
810 | 809 | raise ValidationError(self.error_messages['invalid_choice'] % {'value': value}) |
811 | 810 | return value |
812 | 811 | |
813 | | def validate(self, value): |
814 | | pass |
815 | | |
816 | 812 | |
817 | 813 | class MultipleChoiceField(ChoiceField): |
818 | 814 | hidden_widget = MultipleHiddenInput |
… |
… |
class TypedMultipleChoiceField(MultipleChoiceField):
|
864 | 860 | right type. |
865 | 861 | """ |
866 | 862 | value = super(TypedMultipleChoiceField, self).to_python(value) |
867 | | super(TypedMultipleChoiceField, self).validate(value) |
868 | 863 | if value == self.empty_value or value in self.empty_values: |
869 | 864 | return self.empty_value |
870 | 865 | new_value = [] |
… |
… |
class TypedMultipleChoiceField(MultipleChoiceField):
|
876 | 871 | return new_value |
877 | 872 | |
878 | 873 | def validate(self, value): |
879 | | pass |
| 874 | if value == self.empty_value: |
| 875 | if self.required: |
| 876 | raise ValidationError(self.error_messages['required']) |
| 877 | else: |
| 878 | super(TypedMultipleChoiceField, self).validate(value) |
| 879 | |
880 | 880 | |
881 | 881 | class ComboField(Field): |
882 | 882 | """ |
diff --git a/tests/forms_tests/tests/fields.py b/tests/forms_tests/tests/fields.py
index 3d3206e..95e14c4 100644
a
|
b
|
class FieldsTests(SimpleTestCase):
|
911 | 911 | f = TypedChoiceField(choices=[(1, "+1"), (-1, "-1")], coerce=int, required=False, empty_value=None) |
912 | 912 | self.assertEqual(None, f.clean('')) |
913 | 913 | |
| 914 | def test_typedchoicefield_has_changed(self): |
| 915 | # has_changed should not trigger required validation |
| 916 | f = TypedChoiceField(choices=[(1, "+1"), (-1, "-1")], coerce=int, required=True) |
| 917 | self.assertFalse(f._has_changed(None, '')) |
| 918 | |
914 | 919 | # NullBooleanField ############################################################ |
915 | 920 | |
916 | 921 | def test_nullbooleanfield_1(self): |
… |
… |
class FieldsTests(SimpleTestCase):
|
1060 | 1065 | f = TypedMultipleChoiceField(choices=[(1, "+1"), (-1, "-1")], coerce=int, required=False, empty_value=None) |
1061 | 1066 | self.assertEqual(None, f.clean([])) |
1062 | 1067 | |
| 1068 | def test_typedmultiplechoicefield_has_changed(self): |
| 1069 | # has_changed should not trigger required validation |
| 1070 | f = TypedMultipleChoiceField(choices=[(1, "+1"), (-1, "-1")], coerce=int, required=True) |
| 1071 | self.assertFalse(f._has_changed(None, '')) |
| 1072 | |
1063 | 1073 | # ComboField ################################################################## |
1064 | 1074 | |
1065 | 1075 | def test_combofield_1(self): |
diff --git a/tests/forms_tests/tests/regressions.py b/tests/forms_tests/tests/regressions.py
index 4249b8a..ba741bc 100644
a
|
b
|
class FormsRegressionsTestCase(TestCase):
|
61 | 61 | UNITS = ((b'\xd0\xbc\xd0\xb5\xd1\x81.', b'\xd0\xbc\xd0\xb5\xd1\x81.'), |
62 | 62 | (b'\xd1\x88\xd1\x82.', b'\xd1\x88\xd1\x82.')) |
63 | 63 | f = ChoiceField(choices=UNITS) |
64 | | self.assertEqual(f.clean('\u0448\u0442.'), '\u0448\u0442.') |
65 | 64 | with warnings.catch_warnings(): |
66 | 65 | # Ignore UnicodeWarning |
67 | 66 | warnings.simplefilter("ignore") |
| 67 | self.assertEqual(f.clean('\u0448\u0442.'), '\u0448\u0442.') |
68 | 68 | self.assertEqual(f.clean(b'\xd1\x88\xd1\x82.'), '\u0448\u0442.') |
69 | 69 | |
70 | 70 | # Translated error messages used to be buggy. |