Reputation:
So, I have a decimalfield that can be 3 different values. In my view, I pass in a dictionary of values that contains the appropriate decimal values as keys.
{% for item in booklist %}
{% for key, value in numvec.items %}
{{item.number}}
{% ifequals item.number {{key}} %}
{{value}}
{% endifequals %}
{% endfor %}
{% endfor %}
this is the dict I pass in as numvec:
numvec = {"TEST":Decimal("0.999"), "TEST2":Decimal("0.500"),
"TEST3":Decimal("0.255")}
the number field was defined as having these choices in my model:
BOOK_CHOICES=((Decimal("0.999"), 'TEST'),(Decimal("0.500"), 'TEST2'),(Decimal("0.255"), 'TEST3'),)
The item number prints out just fine in the view if I compare the dict with the attribute, but for some reason the ifequals cannot properly compare two decimals together. Is this a bug, or am I doing something wrong in my template with ifequals?
Upvotes: 1
Views: 11232
Reputation: 1345
In contrast, numbers like 1.1 and 2.2 do not have exact representations in binary floating point. >>
E.g. if you
print Decimal(3.59)
you get
3.589999999999999857891452847979962825775146484375
So if you compare two decimals in django template, better to use the answer that @Oleg Sakharov has, or alternatively you can use same method but different formatting string like:
if item|stringformat:".2f" == "3.59"
Upvotes: 0
Reputation: 6639
The solution:
{% for item in decimals %}
{% if item|stringformat:"s" == variable %}
{{ variable }}
{% endif %}
{% endfor %}
works well for comparing a decimal (like the loop) to a string (like a passed value)
Upvotes: 2
Reputation: 1137
It is not a bug and it is possible to achieve what you're trying to do.
However, first of all few remarks about your code:
{% ifequal item.number {{key}} %}
would cause TemplateSyntaxError Exception if you leave double curly brackets inside the "ifequal" or "if" operator.Now the solution:
Here is an example:
{% for item in decimals %}
{% if item|stringformat:"s" == variable %}
{{ variable }}
{% endif %}
{% endfor %}
Upvotes: 11
Reputation: 2779
It's not quite clear if this would help Ardesco but there is template_utils which has if_greater
, if_greater_or_equal
, if_less
, if_less_or_equal
tags (among others) which solve very related cases where a plain ifequals
isn't quite enough.
after installing just add template_utils
do your django settings.py under INSTALLED_APPS
and then put {% load comparison %}
in your template
Upvotes: 0
Reputation: 126571
Simplest solution is to define a method on the model which encapsulates the numeric logic and returns the human-friendly string.
Or you can write a template tag to do it, which is a lot more code, but perhaps preserves the model/view layer separation a bit better.
Upvotes: 0
Reputation: 18474
According to this, it seems you can only compare strings. I'd make my own template tag if I were you.
Upvotes: 2