Fixed #24531 -- Improved CommaSeparatedIntegerField validation.
`','`, `'1,,1'`, `',1'` etc. are no longer considered as valid comma-separated integer lists.
This commit is contained in:
parent
f4cc0c40a8
commit
3e64f3d0fc
|
@ -254,11 +254,14 @@ def ip_address_validators(protocol, unpack_ipv4):
|
|||
raise ValueError("The protocol '%s' is unknown. Supported: %s"
|
||||
% (protocol, list(ip_address_validator_map)))
|
||||
|
||||
comma_separated_int_list_re = re.compile('^[\d,]+$')
|
||||
validate_comma_separated_integer_list = RegexValidator(
|
||||
comma_separated_int_list_re,
|
||||
_('Enter only digits separated by commas.'),
|
||||
'invalid'
|
||||
|
||||
def int_list_validator(sep=',', message=None, code='invalid'):
|
||||
regexp = re.compile('^\d+(?:%s\d+)*$' % re.escape(sep))
|
||||
return RegexValidator(regexp, message=message, code=code)
|
||||
|
||||
|
||||
validate_comma_separated_integer_list = int_list_validator(
|
||||
message=_('Enter only digits separated by commas.'),
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -214,6 +214,16 @@ to, or in lieu of custom ``field.clean()`` methods.
|
|||
A :class:`RegexValidator` instance that ensures a value is a
|
||||
comma-separated list of integers.
|
||||
|
||||
``int_list_validator``
|
||||
----------------------
|
||||
|
||||
.. function:: int_list_validator(sep=',', message=None, code='invalid')
|
||||
|
||||
.. versionadded:: 1.9
|
||||
|
||||
Returns a :class:`RegexValidator` instance that ensures a string
|
||||
consists of integers separated by ``sep``.
|
||||
|
||||
``MaxValueValidator``
|
||||
---------------------
|
||||
|
||||
|
|
|
@ -213,7 +213,8 @@ URLs
|
|||
Validators
|
||||
^^^^^^^^^^
|
||||
|
||||
* ...
|
||||
* Added :func:`django.core.validators.int_list_validator` to generate
|
||||
validators of strings containing integers separated with a custom character.
|
||||
|
||||
Backwards incompatible changes in 1.9
|
||||
=====================================
|
||||
|
@ -321,6 +322,9 @@ Miscellaneous
|
|||
that value to construct absolute URLs have been moved to CSS for easier
|
||||
customization.
|
||||
|
||||
* ``CommaSeparatedIntegerField`` validation has been refined to forbid values
|
||||
like ``','``, ``',1'``, and ``'1,,2'``.
|
||||
|
||||
.. _deprecated-features-1.9:
|
||||
|
||||
Features deprecated in 1.9
|
||||
|
|
|
@ -2136,24 +2136,28 @@ class ModelOtherFieldTests(TestCase):
|
|||
model = CommaSeparatedInteger
|
||||
fields = '__all__'
|
||||
|
||||
f = CommaSeparatedIntegerForm({'field': '1'})
|
||||
self.assertTrue(f.is_valid())
|
||||
self.assertEqual(f.cleaned_data, {'field': '1'})
|
||||
f = CommaSeparatedIntegerForm({'field': '12'})
|
||||
self.assertTrue(f.is_valid())
|
||||
self.assertEqual(f.cleaned_data, {'field': '12'})
|
||||
f = CommaSeparatedIntegerForm({'field': '1,2,3'})
|
||||
self.assertTrue(f.is_valid())
|
||||
self.assertEqual(f.cleaned_data, {'field': '1,2,3'})
|
||||
f = CommaSeparatedIntegerForm({'field': '10,32'})
|
||||
self.assertTrue(f.is_valid())
|
||||
self.assertEqual(f.cleaned_data, {'field': '10,32'})
|
||||
f = CommaSeparatedIntegerForm({'field': '1a,2'})
|
||||
self.assertEqual(f.errors, {'field': ['Enter only digits separated by commas.']})
|
||||
f = CommaSeparatedIntegerForm({'field': ',,,,'})
|
||||
self.assertTrue(f.is_valid())
|
||||
self.assertEqual(f.cleaned_data, {'field': ',,,,'})
|
||||
self.assertEqual(f.errors, {'field': ['Enter only digits separated by commas.']})
|
||||
f = CommaSeparatedIntegerForm({'field': '1.2'})
|
||||
self.assertEqual(f.errors, {'field': ['Enter only digits separated by commas.']})
|
||||
f = CommaSeparatedIntegerForm({'field': '1,a,2'})
|
||||
self.assertEqual(f.errors, {'field': ['Enter only digits separated by commas.']})
|
||||
f = CommaSeparatedIntegerForm({'field': '1,,2'})
|
||||
self.assertTrue(f.is_valid())
|
||||
self.assertEqual(f.cleaned_data, {'field': '1,,2'})
|
||||
f = CommaSeparatedIntegerForm({'field': '1'})
|
||||
self.assertTrue(f.is_valid())
|
||||
self.assertEqual(f.cleaned_data, {'field': '1'})
|
||||
self.assertEqual(f.errors, {'field': ['Enter only digits separated by commas.']})
|
||||
|
||||
def test_url_on_modelform(self):
|
||||
"Check basic URL field validation on model forms"
|
||||
|
|
|
@ -12,9 +12,9 @@ from django.core.exceptions import ValidationError
|
|||
from django.core.validators import (
|
||||
BaseValidator, EmailValidator, MaxLengthValidator, MaxValueValidator,
|
||||
MinLengthValidator, MinValueValidator, RegexValidator, URLValidator,
|
||||
validate_comma_separated_integer_list, validate_email, validate_integer,
|
||||
validate_ipv4_address, validate_ipv6_address, validate_ipv46_address,
|
||||
validate_slug,
|
||||
int_list_validator, validate_comma_separated_integer_list, validate_email,
|
||||
validate_integer, validate_ipv4_address, validate_ipv6_address,
|
||||
validate_ipv46_address, validate_slug,
|
||||
)
|
||||
from django.test import SimpleTestCase
|
||||
from django.test.utils import str_prefix
|
||||
|
@ -120,12 +120,23 @@ TEST_DATA = [
|
|||
(validate_ipv46_address, '12345::', ValidationError),
|
||||
|
||||
(validate_comma_separated_integer_list, '1', None),
|
||||
(validate_comma_separated_integer_list, '12', None),
|
||||
(validate_comma_separated_integer_list, '1,2', None),
|
||||
(validate_comma_separated_integer_list, '1,2,3', None),
|
||||
(validate_comma_separated_integer_list, '1,2,3,', None),
|
||||
(validate_comma_separated_integer_list, '10,32', None),
|
||||
|
||||
(validate_comma_separated_integer_list, '', ValidationError),
|
||||
(validate_comma_separated_integer_list, 'a', ValidationError),
|
||||
(validate_comma_separated_integer_list, 'a,b,c', ValidationError),
|
||||
(validate_comma_separated_integer_list, '1, 2, 3', ValidationError),
|
||||
(validate_comma_separated_integer_list, ',', ValidationError),
|
||||
(validate_comma_separated_integer_list, '1,2,3,', ValidationError),
|
||||
(validate_comma_separated_integer_list, '1,2,', ValidationError),
|
||||
(validate_comma_separated_integer_list, ',1', ValidationError),
|
||||
(validate_comma_separated_integer_list, '1,,2', ValidationError),
|
||||
|
||||
(int_list_validator(sep='.'), '1.2.3', None),
|
||||
(int_list_validator(sep='.'), '1,2,3', ValidationError),
|
||||
|
||||
(MaxValueValidator(10), 10, None),
|
||||
(MaxValueValidator(10), -10, None),
|
||||
|
|
Loading…
Reference in New Issue