Loading django/utils/numberformat.py +19 −4 Original line number Diff line number Diff line Loading @@ -15,12 +15,15 @@ def format(number, decimal_sep, decimal_pos=None, grouping=0, thousand_sep='', * decimal_sep: Decimal separator symbol (for example ".") * decimal_pos: Number of decimal positions * grouping: Number of digits in every group limited by thousand separator * grouping: Number of digits in every group limited by thousand separator. For non-uniform digit grouping, it can be a sequence with the number of digit group sizes following the format used by the Python locale module in locale.localeconv() LC_NUMERIC grouping (e.g. (3, 2, 0)). * thousand_sep: Thousand separator symbol (for example ",") """ use_grouping = settings.USE_L10N and settings.USE_THOUSAND_SEPARATOR use_grouping = use_grouping or force_grouping use_grouping = use_grouping and grouping > 0 use_grouping = use_grouping and grouping != 0 # Make the common case fast if isinstance(number, int) and not use_grouping and not decimal_pos: return mark_safe(six.text_type(number)) Loading @@ -46,10 +49,22 @@ def format(number, decimal_sep, decimal_pos=None, grouping=0, thousand_sep='', dec_part = decimal_sep + dec_part # grouping if use_grouping: try: # if grouping is a sequence intervals = list(grouping) except TypeError: # grouping is a single value intervals = [grouping, 0] active_interval = intervals.pop(0) int_part_gd = '' for cnt, digit in enumerate(int_part[::-1]): if cnt and not cnt % grouping: cnt = 0 for digit in int_part[::-1]: if cnt and cnt == active_interval: if intervals: active_interval = intervals.pop(0) or active_interval int_part_gd += thousand_sep[::-1] cnt = 0 int_part_gd += digit cnt += 1 int_part = int_part_gd[::-1] return sign + int_part + dec_part docs/ref/settings.txt +16 −0 Original line number Diff line number Diff line Loading @@ -1943,12 +1943,28 @@ no grouping will be applied to the number. If this setting is greater than ``0``, then :setting:`THOUSAND_SEPARATOR` will be used as the separator between those groups. Some locales use non-uniform digit grouping, e.g. ``10,00,00,000`` in ``en_IN``. For this case, you can provide a sequence with the number of digit group sizes to be applied. The first number defines the size of the group preceding the decimal delimiter, and each number that follows defines the size of preceding groups. If the sequence is terminated with ``-1``, no further grouping is performed. If the sequence terminates with a ``0``, the last group size is used for the remainder of the number. Example tuple for ``en_IN``:: NUMBER_GROUPING = (3, 2, 0) Note that if :setting:`USE_L10N` is set to ``True``, then the locale-dictated format has higher precedence and will be applied instead. See also :setting:`DECIMAL_SEPARATOR`, :setting:`THOUSAND_SEPARATOR` and :setting:`USE_THOUSAND_SEPARATOR`. .. versionchanged:: 1.11 Support for non-uniform digit grouping was added. .. setting:: PREPEND_WWW ``PREPEND_WWW`` Loading docs/releases/1.11.txt +2 −1 Original line number Diff line number Diff line Loading @@ -166,7 +166,8 @@ Generic Views Internationalization ~~~~~~~~~~~~~~~~~~~~ * ... * Number formatting and the :setting:`NUMBER_GROUPING` setting support non-uniform digit grouping. Management Commands ~~~~~~~~~~~~~~~~~~~ Loading tests/i18n/tests.py +12 −0 Original line number Diff line number Diff line Loading @@ -576,6 +576,18 @@ class FormattingTests(SimpleTestCase): self.assertEqual('-66666.6', nformat(-66666.666, decimal_sep='.', decimal_pos=1)) self.assertEqual('-66666.0', nformat(int('-66666'), decimal_sep='.', decimal_pos=1)) self.assertEqual('10000.0', nformat(self.l, decimal_sep='.', decimal_pos=1)) self.assertEqual( '10,00,00,000.00', nformat(100000000.00, decimal_sep='.', decimal_pos=2, grouping=(3, 2, 0), thousand_sep=',') ) self.assertEqual( '1,0,00,000,0000.00', nformat(10000000000.00, decimal_sep='.', decimal_pos=2, grouping=(4, 3, 2, 1, 0), thousand_sep=',') ) self.assertEqual( '10000,00,000.00', nformat(1000000000.00, decimal_sep='.', decimal_pos=2, grouping=(3, 2, -1), thousand_sep=',') ) # This unusual grouping/force_grouping combination may be triggered by the intcomma filter (#17414) self.assertEqual('10000', nformat(self.l, decimal_sep='.', decimal_pos=0, grouping=0, force_grouping=True)) Loading Loading
django/utils/numberformat.py +19 −4 Original line number Diff line number Diff line Loading @@ -15,12 +15,15 @@ def format(number, decimal_sep, decimal_pos=None, grouping=0, thousand_sep='', * decimal_sep: Decimal separator symbol (for example ".") * decimal_pos: Number of decimal positions * grouping: Number of digits in every group limited by thousand separator * grouping: Number of digits in every group limited by thousand separator. For non-uniform digit grouping, it can be a sequence with the number of digit group sizes following the format used by the Python locale module in locale.localeconv() LC_NUMERIC grouping (e.g. (3, 2, 0)). * thousand_sep: Thousand separator symbol (for example ",") """ use_grouping = settings.USE_L10N and settings.USE_THOUSAND_SEPARATOR use_grouping = use_grouping or force_grouping use_grouping = use_grouping and grouping > 0 use_grouping = use_grouping and grouping != 0 # Make the common case fast if isinstance(number, int) and not use_grouping and not decimal_pos: return mark_safe(six.text_type(number)) Loading @@ -46,10 +49,22 @@ def format(number, decimal_sep, decimal_pos=None, grouping=0, thousand_sep='', dec_part = decimal_sep + dec_part # grouping if use_grouping: try: # if grouping is a sequence intervals = list(grouping) except TypeError: # grouping is a single value intervals = [grouping, 0] active_interval = intervals.pop(0) int_part_gd = '' for cnt, digit in enumerate(int_part[::-1]): if cnt and not cnt % grouping: cnt = 0 for digit in int_part[::-1]: if cnt and cnt == active_interval: if intervals: active_interval = intervals.pop(0) or active_interval int_part_gd += thousand_sep[::-1] cnt = 0 int_part_gd += digit cnt += 1 int_part = int_part_gd[::-1] return sign + int_part + dec_part
docs/ref/settings.txt +16 −0 Original line number Diff line number Diff line Loading @@ -1943,12 +1943,28 @@ no grouping will be applied to the number. If this setting is greater than ``0``, then :setting:`THOUSAND_SEPARATOR` will be used as the separator between those groups. Some locales use non-uniform digit grouping, e.g. ``10,00,00,000`` in ``en_IN``. For this case, you can provide a sequence with the number of digit group sizes to be applied. The first number defines the size of the group preceding the decimal delimiter, and each number that follows defines the size of preceding groups. If the sequence is terminated with ``-1``, no further grouping is performed. If the sequence terminates with a ``0``, the last group size is used for the remainder of the number. Example tuple for ``en_IN``:: NUMBER_GROUPING = (3, 2, 0) Note that if :setting:`USE_L10N` is set to ``True``, then the locale-dictated format has higher precedence and will be applied instead. See also :setting:`DECIMAL_SEPARATOR`, :setting:`THOUSAND_SEPARATOR` and :setting:`USE_THOUSAND_SEPARATOR`. .. versionchanged:: 1.11 Support for non-uniform digit grouping was added. .. setting:: PREPEND_WWW ``PREPEND_WWW`` Loading
docs/releases/1.11.txt +2 −1 Original line number Diff line number Diff line Loading @@ -166,7 +166,8 @@ Generic Views Internationalization ~~~~~~~~~~~~~~~~~~~~ * ... * Number formatting and the :setting:`NUMBER_GROUPING` setting support non-uniform digit grouping. Management Commands ~~~~~~~~~~~~~~~~~~~ Loading
tests/i18n/tests.py +12 −0 Original line number Diff line number Diff line Loading @@ -576,6 +576,18 @@ class FormattingTests(SimpleTestCase): self.assertEqual('-66666.6', nformat(-66666.666, decimal_sep='.', decimal_pos=1)) self.assertEqual('-66666.0', nformat(int('-66666'), decimal_sep='.', decimal_pos=1)) self.assertEqual('10000.0', nformat(self.l, decimal_sep='.', decimal_pos=1)) self.assertEqual( '10,00,00,000.00', nformat(100000000.00, decimal_sep='.', decimal_pos=2, grouping=(3, 2, 0), thousand_sep=',') ) self.assertEqual( '1,0,00,000,0000.00', nformat(10000000000.00, decimal_sep='.', decimal_pos=2, grouping=(4, 3, 2, 1, 0), thousand_sep=',') ) self.assertEqual( '10000,00,000.00', nformat(1000000000.00, decimal_sep='.', decimal_pos=2, grouping=(3, 2, -1), thousand_sep=',') ) # This unusual grouping/force_grouping combination may be triggered by the intcomma filter (#17414) self.assertEqual('10000', nformat(self.l, decimal_sep='.', decimal_pos=0, grouping=0, force_grouping=True)) Loading