Author: mtredinnick
Date: 2007-07-13 04:09:59 -0500 (Fri, 13 Jul 2007)
New Revision: 5680
Modified:
django/trunk/django/core/validators.py
django/trunk/django/newforms/fields.py
django/trunk/tests/regressiontests/forms/tests.py
Log:
Fixed #4807 -- Fixed a couple of corner cases in decimal form input validation.
Based on a suggestion from Chriss Moffit.
Modified: django/trunk/django/core/validators.py
===================================================================
--- django/trunk/django/core/validators.py 2007-07-13 08:52:07 UTC (rev
5679)
+++ django/trunk/django/core/validators.py 2007-07-13 09:09:59 UTC (rev
5680)
@@ -14,6 +14,10 @@
from django.utils.functional import Promise, lazy
from django.utils.encoding import force_unicode
import re
+try:
+ from decimal import Decimal, DecimalException
+except ImportError:
+ from django.utils._decimal import Decimal, DecimalException # Python 2.3
_datere = r'\d{4}-\d{1,2}-\d{1,2}'
_timere = r'(?:[01]?[0-9]|2[0-3]):[0-5][0-9](?::[0-5][0-9])?'
@@ -26,7 +30,6 @@
r"(^[-!#$%&'*+/=?^_`{}|~0-9A-Z]+(\.[-!#$%&'*+/=?^_`{}|~0-9A-Z]+)*" #
dot-atom
r'|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\001-\011\013\014\016-\177])*"'
# quoted-string
r')@(?:[A-Z0-9-]+\.)+[A-Z]{2,6}$', re.IGNORECASE) # domain
-decimal_re = re.compile(r'^-?(?P<digits>\d+)(\.(?P<decimals>\d+))?$')
integer_re = re.compile(r'^-?\d+$')
ip4_re =
re.compile(r'^(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}$')
phone_re = re.compile(r'^[A-PR-Y0-9]{3}-[A-PR-Y0-9]{3}-[A-PR-Y0-9]{4}$',
re.IGNORECASE)
@@ -415,13 +418,15 @@
self.max_digits, self.decimal_places = max_digits, decimal_places
def __call__(self, field_data, all_data):
- match = decimal_re.search(str(field_data))
- if not match:
+ try:
+ val = Decimal(field_data)
+ except DecimalException:
raise ValidationError, _("Please enter a valid decimal number.")
-
- digits = len(match.group('digits') or '')
- decimals = len(match.group('decimals') or '')
-
+
+ pieces = str(val).split('.')
+ decimals = (len(pieces) == 2) and len(pieces[1]) or 0
+ digits = len(pieces[0])
+
if digits + decimals > self.max_digits:
raise ValidationError, ungettext("Please enter a valid decimal
number with at most %s total digit.",
"Please enter a valid decimal number with at most %s total
digits.", self.max_digits) % self.max_digits
Modified: django/trunk/django/newforms/fields.py
===================================================================
--- django/trunk/django/newforms/fields.py 2007-07-13 08:52:07 UTC (rev
5679)
+++ django/trunk/django/newforms/fields.py 2007-07-13 09:09:59 UTC (rev
5680)
@@ -12,6 +12,11 @@
from util import ErrorList, ValidationError
from widgets import TextInput, PasswordInput, HiddenInput,
MultipleHiddenInput, CheckboxInput, Select, NullBooleanSelect, SelectMultiple
+try:
+ from decimal import Decimal, DecimalException
+except ImportError:
+ from django.utils._decimal import Decimal, DecimalException
+
__all__ = (
'Field', 'CharField', 'IntegerField',
'DEFAULT_DATE_INPUT_FORMATS', 'DateField',
@@ -162,8 +167,6 @@
raise ValidationError(ugettext('Ensure this value is greater than
or equal to %s.') % self.min_value)
return value
-decimal_re = re.compile(r'^-?(?P<digits>\d+)(\.(?P<decimals>\d+))?$')
-
class DecimalField(Field):
def __init__(self, max_value=None, min_value=None, max_digits=None,
decimal_places=None, *args, **kwargs):
self.max_value, self.min_value = max_value, min_value
@@ -181,13 +184,13 @@
if not self.required and value in EMPTY_VALUES:
return None
value = value.strip()
- match = decimal_re.search(value)
- if not match:
+ try:
+ value = Decimal(value)
+ except DecimalException:
raise ValidationError(ugettext('Enter a number.'))
- else:
- value = Decimal(value)
- digits = len(match.group('digits') or '')
- decimals = len(match.group('decimals') or '')
+ pieces = str(value).split('.')
+ decimals = (len(pieces) == 2) and len(pieces[1]) or 0
+ digits = len(pieces[0])
if self.max_value is not None and value > self.max_value:
raise ValidationError(ugettext('Ensure this value is less than or
equal to %s.') % self.max_value)
if self.min_value is not None and value < self.min_value:
Modified: django/trunk/tests/regressiontests/forms/tests.py
===================================================================
--- django/trunk/tests/regressiontests/forms/tests.py 2007-07-13 08:52:07 UTC
(rev 5679)
+++ django/trunk/tests/regressiontests/forms/tests.py 2007-07-13 09:09:59 UTC
(rev 5680)
@@ -1176,6 +1176,10 @@
Decimal("1.5")
>>> f.clean('0.5')
Decimal("0.5")
+>>> f.clean('.5')
+Decimal("0.5")
+>>> f.clean('00.50')
+Decimal("0.50")
# DateField ###################################################################
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/django-updates?hl=en
-~----------~----~----~----~------~----~------~--~---