mirror of
https://github.com/django/django.git
synced 2025-02-02 21:59:53 +00:00
Fixed #25920 -- Added support for non-uniform NUMBER_GROUPING.
This commit is contained in:
parent
46338296aa
commit
b5a1c3a6f5
@ -15,12 +15,15 @@ def format(number, decimal_sep, decimal_pos=None, grouping=0, thousand_sep='',
|
|||||||
|
|
||||||
* decimal_sep: Decimal separator symbol (for example ".")
|
* decimal_sep: Decimal separator symbol (for example ".")
|
||||||
* decimal_pos: Number of decimal positions
|
* 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 ",")
|
* thousand_sep: Thousand separator symbol (for example ",")
|
||||||
"""
|
"""
|
||||||
use_grouping = settings.USE_L10N and settings.USE_THOUSAND_SEPARATOR
|
use_grouping = settings.USE_L10N and settings.USE_THOUSAND_SEPARATOR
|
||||||
use_grouping = use_grouping or force_grouping
|
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
|
# Make the common case fast
|
||||||
if isinstance(number, int) and not use_grouping and not decimal_pos:
|
if isinstance(number, int) and not use_grouping and not decimal_pos:
|
||||||
return mark_safe(six.text_type(number))
|
return mark_safe(six.text_type(number))
|
||||||
@ -46,10 +49,22 @@ def format(number, decimal_sep, decimal_pos=None, grouping=0, thousand_sep='',
|
|||||||
dec_part = decimal_sep + dec_part
|
dec_part = decimal_sep + dec_part
|
||||||
# grouping
|
# grouping
|
||||||
if use_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 = ''
|
int_part_gd = ''
|
||||||
for cnt, digit in enumerate(int_part[::-1]):
|
cnt = 0
|
||||||
if cnt and not cnt % grouping:
|
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]
|
int_part_gd += thousand_sep[::-1]
|
||||||
|
cnt = 0
|
||||||
int_part_gd += digit
|
int_part_gd += digit
|
||||||
|
cnt += 1
|
||||||
int_part = int_part_gd[::-1]
|
int_part = int_part_gd[::-1]
|
||||||
return sign + int_part + dec_part
|
return sign + int_part + dec_part
|
||||||
|
@ -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
|
``0``, then :setting:`THOUSAND_SEPARATOR` will be used as the separator between
|
||||||
those groups.
|
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
|
Note that if :setting:`USE_L10N` is set to ``True``, then the locale-dictated
|
||||||
format has higher precedence and will be applied instead.
|
format has higher precedence and will be applied instead.
|
||||||
|
|
||||||
See also :setting:`DECIMAL_SEPARATOR`, :setting:`THOUSAND_SEPARATOR` and
|
See also :setting:`DECIMAL_SEPARATOR`, :setting:`THOUSAND_SEPARATOR` and
|
||||||
:setting:`USE_THOUSAND_SEPARATOR`.
|
:setting:`USE_THOUSAND_SEPARATOR`.
|
||||||
|
|
||||||
|
.. versionchanged:: 1.11
|
||||||
|
|
||||||
|
Support for non-uniform digit grouping was added.
|
||||||
|
|
||||||
.. setting:: PREPEND_WWW
|
.. setting:: PREPEND_WWW
|
||||||
|
|
||||||
``PREPEND_WWW``
|
``PREPEND_WWW``
|
||||||
|
@ -166,7 +166,8 @@ Generic Views
|
|||||||
Internationalization
|
Internationalization
|
||||||
~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
* ...
|
* Number formatting and the :setting:`NUMBER_GROUPING` setting support
|
||||||
|
non-uniform digit grouping.
|
||||||
|
|
||||||
Management Commands
|
Management Commands
|
||||||
~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~
|
||||||
|
@ -576,6 +576,18 @@ class FormattingTests(SimpleTestCase):
|
|||||||
self.assertEqual('-66666.6', nformat(-66666.666, decimal_sep='.', decimal_pos=1))
|
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('-66666.0', nformat(int('-66666'), decimal_sep='.', decimal_pos=1))
|
||||||
self.assertEqual('10000.0', nformat(self.l, 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)
|
# 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))
|
self.assertEqual('10000', nformat(self.l, decimal_sep='.', decimal_pos=0, grouping=0, force_grouping=True))
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user