mirror of
https://github.com/django/django.git
synced 2024-12-22 17:16:24 +00:00
Fixed #20601 -- Allowed forcing format with thousand separators in floatformat filter.
Thanks Claude Paroz and Nick Pope for reviews.
This commit is contained in:
parent
e18156b6c3
commit
ac6c426007
@ -119,9 +119,20 @@ def floatformat(text, arg=-1):
|
||||
* {{ num2|floatformat:"-3" }} displays "34"
|
||||
* {{ num3|floatformat:"-3" }} displays "34.260"
|
||||
|
||||
If arg has the 'g' suffix, force the result to be grouped by the
|
||||
THOUSAND_SEPARATOR for the active locale. When the active locale is
|
||||
en (English):
|
||||
|
||||
* {{ 6666.6666|floatformat:"2g" }} displays "6,666.67"
|
||||
* {{ 10000|floatformat:"g" }} displays "10,000"
|
||||
|
||||
If the input float is infinity or NaN, display the string representation
|
||||
of that value.
|
||||
"""
|
||||
force_grouping = False
|
||||
if isinstance(arg, str) and arg.endswith('g'):
|
||||
force_grouping = True
|
||||
arg = arg[:-1] or -1
|
||||
try:
|
||||
input_val = repr(text)
|
||||
d = Decimal(input_val)
|
||||
@ -141,7 +152,9 @@ def floatformat(text, arg=-1):
|
||||
return input_val
|
||||
|
||||
if not m and p < 0:
|
||||
return mark_safe(formats.number_format('%d' % (int(d)), 0))
|
||||
return mark_safe(
|
||||
formats.number_format('%d' % (int(d)), 0, force_grouping=force_grouping),
|
||||
)
|
||||
|
||||
exp = Decimal(1).scaleb(-abs(p))
|
||||
# Set the precision high enough to avoid an exception (#15789).
|
||||
@ -161,7 +174,9 @@ def floatformat(text, arg=-1):
|
||||
if sign and rounded_d:
|
||||
digits.append('-')
|
||||
number = ''.join(reversed(digits))
|
||||
return mark_safe(formats.number_format(number, abs(p)))
|
||||
return mark_safe(
|
||||
formats.number_format(number, abs(p), force_grouping=force_grouping),
|
||||
)
|
||||
|
||||
|
||||
@register.filter(is_safe=True)
|
||||
|
@ -1732,6 +1732,18 @@ displayed. For example:
|
||||
``34.26000`` ``{{ value|floatformat:"-3" }}`` ``34.260``
|
||||
============ ================================ ==========
|
||||
|
||||
If the argument passed to ``floatformat`` has the ``g`` suffix, it will force
|
||||
grouping by the :setting:`THOUSAND_SEPARATOR` for the active locale. For
|
||||
example, when the active locale is ``en`` (English):
|
||||
|
||||
============ ================================= =============
|
||||
``value`` Template Output
|
||||
============ ================================= =============
|
||||
``34232.34`` ``{{ value|floatformat:"2g" }}`` ``34,232.34``
|
||||
``34232.06`` ``{{ value|floatformat:"g" }}`` ``34,232.1``
|
||||
``34232.00`` ``{{ value|floatformat:"-3g" }}`` ``34,232``
|
||||
============ ================================= =============
|
||||
|
||||
Using ``floatformat`` with no argument is equivalent to using ``floatformat``
|
||||
with an argument of ``-1``.
|
||||
|
||||
@ -1740,6 +1752,10 @@ with an argument of ``-1``.
|
||||
In older versions, a negative zero ``-0`` was returned for negative numbers
|
||||
which round to zero.
|
||||
|
||||
.. versionchanged:: 3.2
|
||||
|
||||
The ``g`` suffix to force grouping by thousand separators was added.
|
||||
|
||||
.. templatefilter:: force_escape
|
||||
|
||||
``force_escape``
|
||||
|
@ -367,7 +367,8 @@ Signals
|
||||
Templates
|
||||
~~~~~~~~~
|
||||
|
||||
* ...
|
||||
* :tfilter:`floatformat` template filter now allows using the ``g`` suffix to
|
||||
force grouping by the :setting:`THOUSAND_SEPARATOR` for the active locale.
|
||||
|
||||
Tests
|
||||
~~~~~
|
||||
|
@ -560,6 +560,14 @@ class FormattingTests(SimpleTestCase):
|
||||
self.assertEqual('des. 31, 2009, 8:50 p.m.', Template('{{ dt }}').render(self.ctxt))
|
||||
self.assertEqual('66666.67', Template('{{ n|floatformat:2 }}').render(self.ctxt))
|
||||
self.assertEqual('100000.0', Template('{{ f|floatformat }}').render(self.ctxt))
|
||||
self.assertEqual(
|
||||
'66666.67',
|
||||
Template('{{ n|floatformat:"2g" }}').render(self.ctxt),
|
||||
)
|
||||
self.assertEqual(
|
||||
'100000.0',
|
||||
Template('{{ f|floatformat:"g" }}').render(self.ctxt),
|
||||
)
|
||||
self.assertEqual('10:15 a.m.', Template('{{ t|time:"TIME_FORMAT" }}').render(self.ctxt))
|
||||
self.assertEqual('12/31/2009', Template('{{ d|date:"SHORT_DATE_FORMAT" }}').render(self.ctxt))
|
||||
self.assertEqual(
|
||||
@ -734,6 +742,14 @@ class FormattingTests(SimpleTestCase):
|
||||
self.assertEqual('31 de desembre de 2009 a les 20:50', Template('{{ dt }}').render(self.ctxt))
|
||||
self.assertEqual('66666,67', Template('{{ n|floatformat:2 }}').render(self.ctxt))
|
||||
self.assertEqual('100000,0', Template('{{ f|floatformat }}').render(self.ctxt))
|
||||
self.assertEqual(
|
||||
'66.666,67',
|
||||
Template('{{ n|floatformat:"2g" }}').render(self.ctxt),
|
||||
)
|
||||
self.assertEqual(
|
||||
'100.000,0',
|
||||
Template('{{ f|floatformat:"g" }}').render(self.ctxt),
|
||||
)
|
||||
self.assertEqual('10:15', Template('{{ t|time:"TIME_FORMAT" }}').render(self.ctxt))
|
||||
self.assertEqual('31/12/2009', Template('{{ d|date:"SHORT_DATE_FORMAT" }}').render(self.ctxt))
|
||||
self.assertEqual(
|
||||
@ -935,6 +951,14 @@ class FormattingTests(SimpleTestCase):
|
||||
self.assertEqual('Dec. 31, 2009, 8:50 p.m.', Template('{{ dt }}').render(self.ctxt))
|
||||
self.assertEqual('66666.67', Template('{{ n|floatformat:2 }}').render(self.ctxt))
|
||||
self.assertEqual('100000.0', Template('{{ f|floatformat }}').render(self.ctxt))
|
||||
self.assertEqual(
|
||||
'66,666.67',
|
||||
Template('{{ n|floatformat:"2g" }}').render(self.ctxt),
|
||||
)
|
||||
self.assertEqual(
|
||||
'100,000.0',
|
||||
Template('{{ f|floatformat:"g" }}').render(self.ctxt),
|
||||
)
|
||||
self.assertEqual('12/31/2009', Template('{{ d|date:"SHORT_DATE_FORMAT" }}').render(self.ctxt))
|
||||
self.assertEqual(
|
||||
'12/31/2009 8:50 p.m.',
|
||||
|
@ -2,6 +2,8 @@ from decimal import Decimal, localcontext
|
||||
|
||||
from django.template.defaultfilters import floatformat
|
||||
from django.test import SimpleTestCase
|
||||
from django.test.utils import override_settings
|
||||
from django.utils import translation
|
||||
from django.utils.safestring import mark_safe
|
||||
|
||||
from ..utils import setup
|
||||
@ -58,6 +60,19 @@ class FunctionTests(SimpleTestCase):
|
||||
self.assertEqual(floatformat(1.5e-15, -20), '0.00000000000000150000')
|
||||
self.assertEqual(floatformat(1.00000000000000015, 16), '1.0000000000000002')
|
||||
|
||||
@override_settings(USE_L10N=True)
|
||||
def test_force_grouping(self):
|
||||
with translation.override('en'):
|
||||
self.assertEqual(floatformat(10000, 'g'), '10,000')
|
||||
self.assertEqual(floatformat(66666.666, '1g'), '66,666.7')
|
||||
# Invalid suffix.
|
||||
self.assertEqual(floatformat(10000, 'g2'), '10000')
|
||||
with translation.override('de', deactivate=True):
|
||||
self.assertEqual(floatformat(10000, 'g'), '10.000')
|
||||
self.assertEqual(floatformat(66666.666, '1g'), '66.666,7')
|
||||
# Invalid suffix.
|
||||
self.assertEqual(floatformat(10000, 'g2'), '10000')
|
||||
|
||||
def test_zero_values(self):
|
||||
self.assertEqual(floatformat(0, 6), '0.000000')
|
||||
self.assertEqual(floatformat(0, 7), '0.0000000')
|
||||
|
Loading…
Reference in New Issue
Block a user