Reputation: 12910
I am trying to create a rating (stars) ui within my app. All of my 'ratings' come in as float
. I want to round that rating to make it an integer and display that many stars. I can't seem to figure out how to get jinja to like it.
Example Ratings: 3.0
, 2.3
, 5.0
, 4.6
, etc...
Fails because with TypeError: 'float' object cannot be interpreted as an integer
{% if book.average_score %}
{% for s in range(book.average_score) %}
<i class="fas fa-star"></i>
{% endfor %}
{% endif %}
I thought I could just use math
:
{% if book.average_score %}
{% for s in range(math.ceil(book.average_score)) %}
<i class="fas fa-star"></i>
{% endfor %}
{% endif %}
But, this results in jinja2.exceptions.UndefinedError: 'math' is undefined
. I'm assuming this is because I'm using Flask and the template has no idea about the math
library.
I then was playing around with round
:
{% if book.average_score %}
{% for s in range(round(book.average_score)) %}
<i class="fas fa-star"></i>
{% endfor %}
{% endif %}
But then I end up with jinja2.exceptions.UndefinedError: 'round' is undefined
I did some more variations of using round
following the round documentation but no success. I know in Angular, you have pipes
that really help with these sort of things. Does jinja have something similar or am I just way off the mark here?
This SOF thread seems to be the closest thing I can find to the problem I'm trying to solve. Doesn't seem to get me too much further, however.
Upvotes: 2
Views: 8103
Reputation: 311750
You're using Jinja, but you've linked to Python function documentation. Jinja != Python: you need to use filters or object methods when working with Jinja expressions. So, for example, you could use the int filter:
{% if book.average_score %}
{% for s in range(book.average_score|int) %}
<i class="fas fa-star"></i>
{% endfor %}
{% endif %}
Or the round filter:
{% if book.average_score %}
{% for s in range(book.average_score|round) %}
<i class="fas fa-star"></i>
{% endfor %}
{% endif %}
You can control the behavior of the round
filter with the method
parameter, which can be either common
(the default), floor
, or ceil
:
{% if book.average_score %}
{% for s in range(book.average_score|round(method='ceil')) %}
<i class="fas fa-star"></i>
{% endfor %}
{% endif %}
Update
It looks like since this was written that the round
filter may have changed. Looking at the documentation, the mode
parameter doesn't exist, but there is a method
parameter. The following work:
Specify a precision and a method; no keyword args required:
>>> t = jinja2.Template("Value: {{ value|round(2, 'ceil') }}")
>>> print(t.render(value=4.1234))
Value: 4.13
Specify just a rounding method; use the method
keyword:
>>> t = jinja2.Template("Value: {{ value|round(method='ceil') }}")
>>> print(t.render(value=4.1234))
Value: 5.0
I've updated the original part of the answer to reflect this change.
Upvotes: 10