Since intcomma wont work with decimals in django 1.5.1 i tried to convert
a decimal to a float in a template, but it wont give me the excepted
output.
When i have the value of 1000.11 it should be 1000,11 in germany, with
intcomma(float(1000,11)) i get 1.000,11. But when i use
Decimal(1000,11)|floatvalue"2"|intcomma, i will get 1,000,11. Thats a bug
or maybe an unwanted behavior.
--
Ticket URL: <https://code.djangoproject.com/ticket/20601>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
* needs_better_patch: => 0
* needs_tests: => 0
* needs_docs: => 0
--
Ticket URL: <https://code.djangoproject.com/ticket/20601#comment:1>
* cc: merb (added)
--
Ticket URL: <https://code.djangoproject.com/ticket/20601#comment:2>
* status: new => assigned
* owner: nobody => merb
--
Ticket URL: <https://code.djangoproject.com/ticket/20601#comment:3>
--
Ticket URL: <https://code.djangoproject.com/ticket/20601#comment:4>
Comment (by merb):
Replying to [ticket:20601 c.schmitt@…]:
> When u use floatvalue "2" and intcomma together in a template the output
of intcomma won't be internationalized.
>
> Since intcomma wont work with decimals in django 1.5.1 i tried to
convert a decimal to a float in a template, but it wont give me the
excepted output.
> When i have the value of 1000.11 it should be 1000,11 in germany, with
intcomma(float(1000,11)) i get 1.000,11. But when i use
Decimal(1000,11)|floatvalue"2"|intcomma, i will get 1,000,11. Thats a bug
or maybe an unwanted behavior.
i meant floatformat not floatvalue.
--
Ticket URL: <https://code.djangoproject.com/ticket/20601#comment:5>
Comment (by merb):
This is the actual humanize function:
{{{
@register.filter(is_safe=True)
def intcomma(value, use_l10n=True):
"""
Converts an integer to a string containing commas every three digits.
For example, 3000 becomes '3,000' and 45000 becomes '45,000'.
"""
if settings.USE_L10N and use_l10n:
try:
if not isinstance(value, float):
value = int(value)
except (TypeError, ValueError):
return intcomma(value, False)
else:
return number_format(value, force_grouping=True)
orig = force_text(value)
new = re.sub("^(-?\d+)(\d{3})", '\g<1>,\g<2>', orig)
if orig == new:
return new
else:
return intcomma(new, use_l10n)
}}}
The problem is that floatformat returns a SafeText type, so it isn't a
instance of float and intcomma gets recalled with use_l10n=False. So this
line gets called:
{{{
new = re.sub("^(-?\d+)(\d{3})", '\g<1>,\g<2>', orig)
}}}
This line will add an , to every 3rd place on the SafeText type so a
string of:
1000,11 or 1000000,11 will be
1,000,11 or 1,000,000,11 which could get converted to an integer, so the
next time intcomma gets called, it thinks that the SafeText type could now
get converted to an integer and will then return himself.
So this will be an uncorrect return value
--
Ticket URL: <https://code.djangoproject.com/ticket/20601#comment:6>
* type: Cleanup/optimization => Bug
--
Ticket URL: <https://code.djangoproject.com/ticket/20601#comment:7>
* status: assigned => new
* owner: merb =>
--
Ticket URL: <https://code.djangoproject.com/ticket/20601#comment:8>
* type: Bug => New feature
* component: Python 2 => Template system
* stage: Unreviewed => Accepted
Comment:
Basically, the issue is that both `intcomma` and `floatformat` take
numbers (or number-convertible values) to output a string representation.
So chaining them is basically broken. One strategy would be to try harder
to make those string representation transformed back to numbers, but then
the first transformation would be lost.
I'm of the opinion that either one of these filters should be able to do
all necessary transformations. For example, we could imagine that the
`floatformat` argument takes an optional `g` suffix to indicate grouping.
So the result of `Decimal(1000,11)|floatvalue:"2g"` would be 1.000,11 for
German (i.e. `numberformat` would be passed `force_grouping=True` in
`floatformat` filter).
--
Ticket URL: <https://code.djangoproject.com/ticket/20601#comment:9>
Comment (by merb):
wouldn't it be better to make them type safe? Like raise an error if
intcomma or floatformat won't get 'numbers' or 'localized_numbers'?
--
Ticket URL: <https://code.djangoproject.com/ticket/20601#comment:10>
* version: 1.5 => 1.10
Comment:
This is still problem in Django 1.10.
--
Ticket URL: <https://code.djangoproject.com/ticket/20601#comment:11>
* cc: Alexey (added)
--
Ticket URL: <https://code.djangoproject.com/ticket/20601#comment:12>
Comment (by Alexey):
Should we try to parse value to float?
Something like try to find float separator with regex, and convert it
before `isinstance` check
--
Ticket URL: <https://code.djangoproject.com/ticket/20601#comment:13>
Comment (by Ron):
For the specific German case a fix:
`'|'.join(intcomma(floatformat(amount, 2)).rsplit(',', 1)).replace(',',
'.').replace('|', ',')`
Maybe this helps anybody...
--
Ticket URL: <https://code.djangoproject.com/ticket/20601#comment:14>
* owner: (none) => Ram Parameswaran
* status: new => assigned
* has_patch: 0 => 1
* version: 1.10 => master
Comment:
[https://github.com/django/django/pull/11834 PR]
--
Ticket URL: <https://code.djangoproject.com/ticket/20601#comment:15>
* needs_better_patch: 0 => 1
--
Ticket URL: <https://code.djangoproject.com/ticket/20601#comment:16>
* needs_better_patch: 1 => 0
Comment:
[https://github.com/django/django/pull/13528 PR]
--
Ticket URL: <https://code.djangoproject.com/ticket/20601#comment:18>
* needs_better_patch: 1 => 0
Comment:
Addressed reviews.
--
Ticket URL: <https://code.djangoproject.com/ticket/20601#comment:20>
* stage: Accepted => Ready for checkin
--
Ticket URL: <https://code.djangoproject.com/ticket/20601#comment:21>
--
Ticket URL: <https://code.djangoproject.com/ticket/20601#comment:22>
* status: assigned => closed
* resolution: => fixed
Comment:
In [changeset:"ac6c4260074de43a978e5c6553ef89441e1d6748" ac6c426]:
{{{
#!CommitTicketReference repository=""
revision="ac6c4260074de43a978e5c6553ef89441e1d6748"
Fixed #20601 -- Allowed forcing format with thousand separators in
floatformat filter.
Thanks Claude Paroz and Nick Pope for reviews.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/20601#comment:23>
Comment (by Cassiano R. N. dos Santos):
Is this fixed for Django 2.2
Doing
{{{
{{ variable | intcomma | floatformat:2 }}
}}}
or
{{{
{{ variable | floatformat:2 | intcomma }}
}}}
does not work.
In the first case results broken, and in second, gives, e.g. 1,000,00 when
the correct would be 1.000,00 for pt-BR (brazilian portuguese).
--
Ticket URL: <https://code.djangoproject.com/ticket/20601#comment:24>
Comment (by Mariusz Felisiak):
Replying to [comment:24 Cassiano R. N. dos Santos]:
> Is this fixed for Django 2.2?
No, it's fixed in Django 3.2+.
--
Ticket URL: <https://code.djangoproject.com/ticket/20601#comment:25>
* cc: Cassiano R. N. dos Santos (added)
* has_patch: 1 => 0
* version: dev => 4.0
* type: New feature => Bug
Comment:
I'm just trying the fix in Django 4.0.1 with both
{{{
{{ variable | intcomma | floatformat:2 }} {# breaks template #}
}}}
and
{{{
{{ variable | floatformat:2 | intcomma }} {# results i.e., 10,123,00
(would be 10.123,00) #}
}}}
But the bug persists.
In my settings.py:
{{{
LANGUAGE_CODE = 'pt-BR'
USE_I18N = True
USE_L10N = True
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/20601#comment:26>
* has_patch: 0 => 1
* type: Bug => New feature
Comment:
Replying to [comment:26 Cassiano R. N. dos Santos]:
> But the bug persists.
I don't see the "g" suffix in your example. Also in Django 4.0 the
`floatformat` template filter no longer depends on the `USE_L10N` setting
and always returns localized output. Have you tried `{{ variable |
floatformat:"2g" }}`?
--
Ticket URL: <https://code.djangoproject.com/ticket/20601#comment:27>
Comment (by Cassiano R. N. dos Santos):
Oh, that was it. It was missing the "2g". Thank you very much.
--
Ticket URL: <https://code.djangoproject.com/ticket/20601#comment:28>