Fixed #11206 -- Ensure that the floatformat template filter doesn't switch to scientific notation when asked to format a zero value with more than six decimal places. Thanks Tai Lee for the report and fix and Facundo Batista for his help when Decimal module expertise was needed.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@15736 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
9428c23869
commit
3ecf628b36
|
@ -149,9 +149,19 @@ def floatformat(text, arg=-1):
|
||||||
if p == 0:
|
if p == 0:
|
||||||
exp = Decimal(1)
|
exp = Decimal(1)
|
||||||
else:
|
else:
|
||||||
exp = Decimal('1.0') / (Decimal(10) ** abs(p))
|
exp = Decimal(u'1.0') / (Decimal(10) ** abs(p))
|
||||||
try:
|
try:
|
||||||
return mark_safe(formats.number_format(u'%s' % str(d.quantize(exp, ROUND_HALF_UP)), abs(p)))
|
# Avoid conversion to scientific notation by accessing `sign`, `digits`
|
||||||
|
# and `exponent` from `Decimal.as_tuple()` directly.
|
||||||
|
sign, digits, exponent = d.quantize(exp, ROUND_HALF_UP).as_tuple()
|
||||||
|
digits = [unicode(digit) for digit in reversed(digits)]
|
||||||
|
while len(digits) <= abs(exponent):
|
||||||
|
digits.append(u'0')
|
||||||
|
digits.insert(-exponent, u'.')
|
||||||
|
if sign:
|
||||||
|
digits.append(u'-')
|
||||||
|
number = u''.join(reversed(digits))
|
||||||
|
return mark_safe(formats.number_format(number, abs(p)))
|
||||||
except InvalidOperation:
|
except InvalidOperation:
|
||||||
return input_val
|
return input_val
|
||||||
floatformat.is_safe = True
|
floatformat.is_safe = True
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
import datetime
|
import datetime
|
||||||
import unittest
|
from django.utils import unittest
|
||||||
|
|
||||||
from django.template.defaultfilters import *
|
from django.template.defaultfilters import *
|
||||||
|
|
||||||
|
@ -29,6 +29,13 @@ class DefaultFiltersTests(unittest.TestCase):
|
||||||
self.assertEqual(floatformat(u'¿Cómo esta usted?'), u'')
|
self.assertEqual(floatformat(u'¿Cómo esta usted?'), u'')
|
||||||
self.assertEqual(floatformat(None), u'')
|
self.assertEqual(floatformat(None), u'')
|
||||||
|
|
||||||
|
# Check that we're not converting to scientific notation.
|
||||||
|
self.assertEqual(floatformat(0, 6), u'0.000000')
|
||||||
|
self.assertEqual(floatformat(0, 7), u'0.0000000')
|
||||||
|
self.assertEqual(floatformat(0, 10), u'0.0000000000')
|
||||||
|
self.assertEqual(floatformat(0.000000000000000000015, 20),
|
||||||
|
u'0.00000000000000000002')
|
||||||
|
|
||||||
pos_inf = float(1e30000)
|
pos_inf = float(1e30000)
|
||||||
self.assertEqual(floatformat(pos_inf), unicode(pos_inf))
|
self.assertEqual(floatformat(pos_inf), unicode(pos_inf))
|
||||||
|
|
||||||
|
@ -46,6 +53,13 @@ class DefaultFiltersTests(unittest.TestCase):
|
||||||
|
|
||||||
self.assertEqual(floatformat(FloatWrapper(11.000001), -2), u'11.00')
|
self.assertEqual(floatformat(FloatWrapper(11.000001), -2), u'11.00')
|
||||||
|
|
||||||
|
# This fails because of Python's float handling. Floats with many zeroes
|
||||||
|
# after the decimal point should be passed in as another type such as
|
||||||
|
# unicode or Decimal.
|
||||||
|
@unittest.expectedFailure
|
||||||
|
def test_floatformat_fail(self):
|
||||||
|
self.assertEqual(floatformat(1.00000000000000015, 16), u'1.0000000000000002')
|
||||||
|
|
||||||
def test_addslashes(self):
|
def test_addslashes(self):
|
||||||
self.assertEqual(addslashes(u'"double quotes" and \'single quotes\''),
|
self.assertEqual(addslashes(u'"double quotes" and \'single quotes\''),
|
||||||
u'\\"double quotes\\" and \\\'single quotes\\\'')
|
u'\\"double quotes\\" and \\\'single quotes\\\'')
|
||||||
|
|
Loading…
Reference in New Issue