From caf56ad1743778bad8af6b51b08f5baa342d4cd2 Mon Sep 17 00:00:00 2001 From: Tome Cvitan Date: Sat, 18 May 2013 13:26:07 +0200 Subject: [PATCH] Fixed #20440 -- Ensured CharField's max_length/min_length are integers --- AUTHORS | 1 + django/forms/fields.py | 14 ++++++++++++-- tests/forms_tests/tests/test_fields.py | 9 +++++++++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/AUTHORS b/AUTHORS index 4a9981d1fe4..6ecda3ff57f 100644 --- a/AUTHORS +++ b/AUTHORS @@ -164,6 +164,7 @@ answer newbie questions, and generally made Django that much better: Leah Culver Raúl Cumplido flavio.curella@gmail.com + Tome Cvitan John D'Agostino dackze+django@gmail.com Jim Dalton diff --git a/django/forms/fields.py b/django/forms/fields.py index 3ef0d72463f..ac68b9f1fc9 100644 --- a/django/forms/fields.py +++ b/django/forms/fields.py @@ -198,14 +198,15 @@ class Field(object): result.validators = self.validators[:] return result + class CharField(Field): def __init__(self, max_length=None, min_length=None, *args, **kwargs): self.max_length, self.min_length = max_length, min_length super(CharField, self).__init__(*args, **kwargs) if min_length is not None: - self.validators.append(validators.MinLengthValidator(min_length)) + self.validators.append(validators.MinLengthValidator(int(min_length))) if max_length is not None: - self.validators.append(validators.MaxLengthValidator(max_length)) + self.validators.append(validators.MaxLengthValidator(int(max_length))) def to_python(self, value): "Returns a Unicode object." @@ -220,6 +221,7 @@ class CharField(Field): attrs.update({'maxlength': str(self.max_length)}) return attrs + class IntegerField(Field): default_error_messages = { 'invalid': _('Enter a whole number.'), @@ -444,6 +446,7 @@ class TimeField(BaseTemporalField): def strptime(self, value, format): return datetime.datetime.strptime(force_str(value), format).time() + class DateTimeField(BaseTemporalField): widget = DateTimeInput input_formats = formats.get_format_lazy('DATETIME_INPUT_FORMATS') @@ -482,6 +485,7 @@ class DateTimeField(BaseTemporalField): def strptime(self, value, format): return datetime.datetime.strptime(force_str(value), format) + class RegexField(CharField): def __init__(self, regex, max_length=None, min_length=None, error_message=None, *args, **kwargs): """ @@ -511,6 +515,7 @@ class RegexField(CharField): regex = property(_get_regex, _set_regex) + class EmailField(CharField): widget = EmailInput default_validators = [validators.validate_email] @@ -519,6 +524,7 @@ class EmailField(CharField): value = self.to_python(value).strip() return super(EmailField, self).clean(value) + class FileField(Field): widget = ClearableFileInput default_error_messages = { @@ -626,6 +632,7 @@ class ImageField(FileField): f.seek(0) return f + class URLField(CharField): widget = URLInput default_error_messages = { @@ -792,6 +799,7 @@ class ChoiceField(Field): return True return False + class TypedChoiceField(ChoiceField): def __init__(self, *args, **kwargs): self.coerce = kwargs.pop('coerce', lambda val: val) @@ -903,6 +911,7 @@ class ComboField(Field): value = field.clean(value) return value + class MultiValueField(Field): """ A Field that aggregates the logic of multiple Fields. @@ -1047,6 +1056,7 @@ class FilePathField(ChoiceField): self.widget.choices = self.choices + class SplitDateTimeField(MultiValueField): widget = SplitDateTimeWidget hidden_widget = SplitHiddenDateTimeWidget diff --git a/tests/forms_tests/tests/test_fields.py b/tests/forms_tests/tests/test_fields.py index 7516de29b47..47c637befa9 100644 --- a/tests/forms_tests/tests/test_fields.py +++ b/tests/forms_tests/tests/test_fields.py @@ -125,6 +125,15 @@ class FieldsTests(SimpleTestCase): self.assertEqual(f.max_length, None) self.assertEqual(f.min_length, 10) + def test_charfield_length_not_int(self): + """ + Ensure that setting min_length or max_length to something that is not a + number returns an exception. + """ + self.assertRaises(ValueError, CharField, min_length='a') + self.assertRaises(ValueError, CharField, max_length='a') + self.assertRaises(ValueError, CharField, 'a') + def test_charfield_widget_attrs(self): """ Ensure that CharField.widget_attrs() always returns a dictionary.