Code

Ticket #6392: 6392.diff

File 6392.diff, 6.5 KB (added by jezdez, 4 years ago)

Updated patch which uses locale-aware formatting.

Line 
1diff --git a/django/contrib/humanize/templatetags/humanize.py b/django/contrib/humanize/templatetags/humanize.py
2index 05d3223..5baf003 100644
3--- a/django/contrib/humanize/templatetags/humanize.py
4+++ b/django/contrib/humanize/templatetags/humanize.py
5@@ -1,9 +1,11 @@
6+import re
7+from datetime import date
8 from django.utils.translation import ungettext, ugettext as _
9 from django.utils.encoding import force_unicode
10+from django.utils.formats import number_format
11 from django import template
12 from django.template import defaultfilters
13-from datetime import date
14-import re
15+from django.conf import settings
16 
17 register = template.Library()
18 
19@@ -28,6 +30,8 @@ def intcomma(value):
20     Converts an integer to a string containing commas every three digits.
21     For example, 3000 becomes '3,000' and 45000 becomes '45,000'.
22     """
23+    if settings.USE_L10N:
24+        return number_format(value)
25     orig = force_unicode(value)
26     new = re.sub("^(-?\d+)(\d{3})", '\g<1>,\g<2>', orig)
27     if orig == new:
28@@ -46,15 +50,33 @@ def intword(value):
29     value = int(value)
30     if value < 1000000:
31         return value
32+
33+    def _check_for_i18n(value, float_formatted, string_formatted):
34+        """
35+        Use the i18n enabled defaultfilters.floatformat if possible
36+        """
37+        if settings.USE_L10N:
38+            return defaultfilters.floatformat(value, 1), string_formatted
39+        return value, float_formatted
40+
41     if value < 1000000000:
42         new_value = value / 1000000.0
43-        return ungettext('%(value).1f million', '%(value).1f million', new_value) % {'value': new_value}
44+        new_value, value_string = _check_for_i18n(new_value,
45+            ungettext('%(value).1f million', '%(value).1f million', new_value),
46+            ungettext('%(value)s million', '%(value)s million', new_value))
47+        return value_string % {'value': new_value}
48     if value < 1000000000000:
49         new_value = value / 1000000000.0
50-        return ungettext('%(value).1f billion', '%(value).1f billion', new_value) % {'value': new_value}
51+        new_value, value_string = _check_for_i18n(new_value,
52+            ungettext('%(value).1f billion', '%(value).1f billion', new_value),
53+            ungettext('%(value)s billion', '%(value)s billion', new_value))
54+        return value_string % {'value': new_value}
55     if value < 1000000000000000:
56         new_value = value / 1000000000000.0
57-        return ungettext('%(value).1f trillion', '%(value).1f trillion', new_value) % {'value': new_value}
58+        new_value, value_string = _check_for_i18n(new_value,
59+            ungettext('%(value).1f trillion', '%(value).1f trillion', new_value),
60+            ungettext('%(value)s trillion', '%(value)s trillion', new_value))
61+        return value_string % {'value': new_value}
62     return value
63 intword.is_safe = False
64 register.filter(intword)
65diff --git a/docs/ref/contrib/humanize.txt b/docs/ref/contrib/humanize.txt
66index 07a62a7..fe90150 100644
67--- a/docs/ref/contrib/humanize.txt
68+++ b/docs/ref/contrib/humanize.txt
69@@ -40,6 +40,12 @@ Examples:
70     * ``450000`` becomes ``'450,000'``.
71     * ``4500000`` becomes ``'4,500,000'``.
72 
73+:ref:`Format localization <format-localization>` will be respected if enabled,
74+e.g. with the ``'de'`` language:
75+
76+    * ``45000`` becomes ``'45.000'``.
77+    * ``450000`` becomes ``'450.000'``.
78+
79 You can pass in either an integer or a string representation of an integer.
80 
81 intword
82@@ -56,6 +62,13 @@ Examples:
83 
84 Values up to 1000000000000000 (one quadrillion) are supported.
85 
86+:ref:`Format localization <format-localization>` will be respected if enabled,
87+e.g. with the ``'de'`` language:
88+
89+    * ``1000000`` becomes ``'1,0 Million'``.
90+    * ``1200000`` becomes ``'1,2 Million'``.
91+    * ``1200000000`` becomes ``'1,2 Milliarde'``.
92+
93 You can pass in either an integer or a string representation of an integer.
94 
95 ordinal
96diff --git a/tests/regressiontests/humanize/tests.py b/tests/regressiontests/humanize/tests.py
97index 6f60c6d..097bcb7 100644
98--- a/tests/regressiontests/humanize/tests.py
99+++ b/tests/regressiontests/humanize/tests.py
100@@ -2,8 +2,9 @@ import unittest
101 from datetime import timedelta, date
102 from django.template import Template, Context, add_to_builtins
103 from django.utils.dateformat import DateFormat
104-from django.utils.translation import ugettext as _
105+from django.utils.translation import ugettext as _, activate, deactivate
106 from django.utils.html import escape
107+from django.conf import settings
108 
109 add_to_builtins('django.contrib.humanize.templatetags.humanize')
110 
111@@ -37,6 +38,22 @@ class HumanizeTests(unittest.TestCase):
112 
113         self.humanize_tester(test_list, result_list, 'intcomma')
114 
115+    def test_i18n_intcomma(self):
116+        test_list = (100, 1000, 10123, 10311, 1000000, 1234567.25,
117+                     '100', '1000', '10123', '10311', '1000000', '1234567.1234567')
118+        result_list = ('100', '1.000', '10.123', '10.311', '1.000.000', '1.234.567,25',
119+                       '100', '1.000', '10.123', '10.311', '1.000.000', '1.234.567,1234567')
120+        _use_l10n = settings.USE_L10N
121+        _use_thousand_separator = settings.USE_THOUSAND_SEPARATOR
122+        settings.USE_L10N = True
123+        settings.USE_THOUSAND_SEPARATOR = True
124+        try:
125+            activate('de')
126+            self.humanize_tester(test_list, result_list, 'intcomma')
127+        finally:
128+            settings.USE_L10N = _use_l10n
129+            deactivate()
130+
131     def test_intword(self):
132         test_list = ('100', '1000000', '1200000', '1290000',
133                      '1000000000','2000000000','6000000000000')
134@@ -45,6 +62,23 @@ class HumanizeTests(unittest.TestCase):
135 
136         self.humanize_tester(test_list, result_list, 'intword')
137 
138+    def test_i18n_intword(self):
139+        test_list = ('100', '1000000', '1200000', '1290000',
140+                     '1000000000','2000000000','6000000000000')
141+        result_list = ('100', '1,0 million', '1,2 million', '1,3 million',
142+                       '1,0 billion', '2,0 billion', '6,0 trillion')
143+        _use_l10n = settings.USE_L10N
144+        _use_thousand_separator = settings.USE_THOUSAND_SEPARATOR
145+        settings.USE_L10N = True
146+        settings.USE_THOUSAND_SEPARATOR = True
147+        try:
148+            activate('de')
149+            self.humanize_tester(test_list, result_list, 'intword')
150+        finally:
151+            settings.USE_L10N = _use_l10n
152+            settings.USE_THOUSAND_SEPARATOR = _use_thousand_separator
153+            deactivate()
154+
155     def test_apnumber(self):
156         test_list = [str(x) for x in range(1, 11)]
157         result_list = (u'one', u'two', u'three', u'four', u'five', u'six',