From 91976f5840f0dafec099c3cc363641146394e541 Mon Sep 17 00:00:00 2001 From: Jacob Walls Date: Sun, 11 Oct 2020 23:34:32 -0400 Subject: [PATCH] Fixed #20601 -- Added suffix `g` to floatformat to force group separators. --- django/template/defaultfilters.py | 16 ++++++++++++++-- docs/ref/templates/builtins.txt | 15 +++++++++++++++ docs/releases/3.2.txt | 5 ++++- tests/i18n/tests.py | 5 +++++ 4 files changed, 38 insertions(+), 3 deletions(-) diff --git a/django/template/defaultfilters.py b/django/template/defaultfilters.py index 8bd865ad80988..4f72164bcbfc3 100644 --- a/django/template/defaultfilters.py +++ b/django/template/defaultfilters.py @@ -119,9 +119,21 @@ def floatformat(text, arg=-1): * {{ num2|floatformat:"-3" }} displays "34" * {{ num3|floatformat:"-3" }} displays "34.260" + Use the suffix ``g`` to force the result to be grouped + (appropriately for the locale, if settings.`USE_L10N` is True): + + * {{ 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): + force_grouping = arg.endswith('g') + arg = arg.strip('g') + if not arg: + arg = -1 try: input_val = repr(text) d = Decimal(input_val) @@ -141,7 +153,7 @@ 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 +173,7 @@ 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) diff --git a/docs/ref/templates/builtins.txt b/docs/ref/templates/builtins.txt index 54258155bde07..0eb8475ea3854 100644 --- a/docs/ref/templates/builtins.txt +++ b/docs/ref/templates/builtins.txt @@ -1732,6 +1732,17 @@ displayed. For example: ``34.26000`` ``{{ value|floatformat:"-3" }}`` ``34.260`` ============ ================================ ========== +Use the suffix ``g`` to force the result to be grouped +(appropriately for the locale, if :setting:`USE_L10N` is ``True``): + +============ ================================= ============= +``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 +1751,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 suffix ``g`` to ensure grouping by separators was added. + .. templatefilter:: force_escape ``force_escape`` diff --git a/docs/releases/3.2.txt b/docs/releases/3.2.txt index ab1d4dfb9a2f1..1f8049997f56f 100644 --- a/docs/releases/3.2.txt +++ b/docs/releases/3.2.txt @@ -367,7 +367,10 @@ Signals Templates ~~~~~~~~~ -* ... +* Decimal place arguments to :tfilter:`floatformat` may now use the suffix + ``g`` to ensure the result is grouped with a separator. Further, the + separator will be appropriate for the locale if :setting:`USE_L10N` is + ``True``. Tests ~~~~~ diff --git a/tests/i18n/tests.py b/tests/i18n/tests.py index affda21fb4278..f600b5d390cab 100644 --- a/tests/i18n/tests.py +++ b/tests/i18n/tests.py @@ -533,6 +533,11 @@ def test_locale_independent(self): self.assertEqual('31.12.2009 в 20:50', Template('{{ dt|date:"d.m.Y в H:i" }}').render(self.ctxt)) self.assertEqual('⌚ 10:15', Template('{{ t|time:"⌚ H:i" }}').render(self.ctxt)) + def test_floatformat_force_grouping(self): + with translation.override('de'): + self.assertEqual('66.666,7', Template('{{ n|floatformat:"1g" }}').render(self.ctxt)) + self.assertEqual('10.000', Template('{{ l|floatformat:"g" }}').render(self.ctxt)) + @override_settings(USE_L10N=False) def test_l10n_disabled(self): """