Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixed #20039 -- Fixed has_changed form detection for required TypedCh…

…oiceFields

Thanks Florian Apolloner for the report and the review.
Also fixes #19643.
  • Loading branch information...
commit 9883551d50e105b324d8071232bf420935844e43 1 parent 6b48349
Claude Paroz authored March 14, 2013
16  django/forms/fields.py
@@ -778,14 +778,15 @@ def validate(self, value):
778 778
 
779 779
     def valid_value(self, value):
780 780
         "Check to see if the provided value is a valid choice"
  781
+        text_value = force_text(value)
781 782
         for k, v in self.choices:
782 783
             if isinstance(v, (list, tuple)):
783 784
                 # This is an optgroup, so look inside the group for options
784 785
                 for k2, v2 in v:
785  
-                    if value == smart_text(k2):
  786
+                    if value == k2 or text_value == force_text(k2):
786 787
                         return True
787 788
             else:
788  
-                if value == smart_text(k):
  789
+                if value == k or text_value == force_text(k):
789 790
                     return True
790 791
         return False
791 792
 
@@ -801,7 +802,6 @@ def to_python(self, value):
801 802
         right type.
802 803
         """
803 804
         value = super(TypedChoiceField, self).to_python(value)
804  
-        super(TypedChoiceField, self).validate(value)
805 805
         if value == self.empty_value or value in self.empty_values:
806 806
             return self.empty_value
807 807
         try:
@@ -810,9 +810,6 @@ def to_python(self, value):
810 810
             raise ValidationError(self.error_messages['invalid_choice'] % {'value': value})
811 811
         return value
812 812
 
813  
-    def validate(self, value):
814  
-        pass
815  
-
816 813
 
817 814
 class MultipleChoiceField(ChoiceField):
818 815
     hidden_widget = MultipleHiddenInput
@@ -864,7 +861,6 @@ def to_python(self, value):
864 861
         right type.
865 862
         """
866 863
         value = super(TypedMultipleChoiceField, self).to_python(value)
867  
-        super(TypedMultipleChoiceField, self).validate(value)
868 864
         if value == self.empty_value or value in self.empty_values:
869 865
             return self.empty_value
870 866
         new_value = []
@@ -876,7 +872,11 @@ def to_python(self, value):
876 872
         return new_value
877 873
 
878 874
     def validate(self, value):
879  
-        pass
  875
+        if value != self.empty_value:
  876
+            super(TypedMultipleChoiceField, self).validate(value)
  877
+        elif self.required:
  878
+            raise ValidationError(self.error_messages['required'])
  879
+
880 880
 
881 881
 class ComboField(Field):
882 882
     """
10  tests/forms_tests/tests/fields.py
@@ -911,6 +911,11 @@ def test_typedchoicefield_6(self):
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):
@@ -1060,6 +1065,11 @@ def test_typedmultiplechoicefield_7(self):
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):
2  tests/forms_tests/tests/regressions.py
@@ -61,10 +61,10 @@ class SomeForm(Form):
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.

0 notes on commit 9883551

Please sign in to comment.
Something went wrong with that request. Please try again.