Wpis z mikrobloga

Natknąłem się na problem.
Piszę sobie prostą apkę, jestem na etapie dodawania kolejnych templatek. Mam sobie obiekt 'hero', który w 'recruitmentpoints' będzie miał wartość pomiędzy 0 a 4. Jeśli wartość będzie wynosiła 0, to ma się wyświelić jedna ikona (to mam), jak wartość jest większa niż 0 to ma się wyswietlić tyle razy inna ikona, ile ta wartość wynosi. Czyli jedna, dwie, trzy albo cztery ikony.
Banał. Jestem pewien, że już to robiłem.
Dokumentacja mówi, że można użyć funkcji range:
http://jinja.pocoo.org/docs/2.10/templates/#list-of-global-functions
to samo mówi stack overflow:
https://stackoverflow.com/questions/17691838/range-in-jinja2-inside-a-for-loop/17691875#17691875

{% for n in range(n) %}
Ja u siebie oczywiście mam:

{% for n in range(hero.recruitment_points) %}
ale nie działa. Błąd: Could not parse the remainder (hero.recruitment_points).
Próbowałem to naprawić na kilka sposobów, ale nie mogę. Wygląda jakby metoda range powodowała problem. Tak uważam, ponieważ:
- usunąłem range, zostawiając samo "for n in hero.recruitment_points" - otrzymałem komunikat, którego się spodziewałem: "'int' is not iterable". Ale mam dowód, że widzi poprawnie recruitment_points przy próbie utworzenia pentli.
- zmieniłem recruitment
points na name (który jest stringiem): "for n in hero.name" i działa tak jak powinno, dodaje tyle razy wspomnianą wcześniej ikonę, ile 'name' ma w sobie liter. Zgadza się.
- nawet próbowałem wstawić proste: "{% for n in range(5) %}" z przykładu z stackoverflow i otrzymałem ponownie: "Could not parse reminder (5) from 'range(5)'.
Jakieś pomysły?

ps: ewentualnymi literówkami w nazwach się nie przejmujcie, kod z mojej apki przepisywałem.

#python
  • 15
@satq: Dlatego, że for n in range(5) miałoby się wykonać 5 razy, a for n in "5" wykona się tylko jeden raz. Uściślając: wykona się tyle razy, jak długi będzie string. A w moim przypadku stringi zawsze będą jednoznakowe.

@Blotny: Myślałem nad różnymi sposobami obejścia tego. Ale to potencjalnie jest apka na której miałbym tłumaczyć przyjaciółce jak wygląda praca z Django i wolałbym, żeby te rozwiązania były w miarę czyste.
@satq: Ale faktycznie znam developerów, którzy w 3 minuty dopisaliby do obiektu jeszcze jedno pole typu string z automatycznie generowaną treścią 'x'*recruitment_ponts i mieliby po czym pętle później robic :D
@venomik: u siebie w projekcie mam to tak rozwiązane:
https://pastebin.com/Ejp2TEtP

rejestruje filter, który wywołany w template zwraca mi string w formacie:
znak 'f' - pełna gwiazdka
znak 'h' - pół gwiazki
znak 'e' - pusta gwiazdka
korzystam do tego z awesomefonts

rank to zmienna, która zawiera ocene - ilość gwiazdek ( u Ciebie recruitment_points )
@b3rly: Jasne, rozumiem takie rozwiązanie. I jest spoko w sytuacji kiedy są różne ikony dla różnych wartości. Ja mam powtarzające się te same ikony. Więc by kod wyglądał bardziej:

{% if hero.recruitment_points == 1 %}

{% elif hero.recruitment_points == 2 %}

{% elif hero.recruitment_points == 3 %}

Więc wciaż brzydko. Bez pętli się tego 'względnie sensownie' chyba nie da zrobić.

Zdaję sobie sprawę jakie rozwiązanie się narzuca. Przygotowanie ikon:
recruitment_icon_1 -
@venomik: to zarejestruj po prostu filter, który Ci wzróci string o zadanej długości
np. dla {% for star in 5|stars %} --> {% for star in "xxxxx" %}
a dalej to już możesz wyświetlać co chcesz te 5 razy :)
@b3rly:
:D
Myślałem, żeby cos takiego w samej templatce zrobić. Wiesz, na zasadzie:
for i in hero.recruitment_points*'x'
ale nie udało mi się sprawić aby coś podobnie jednolinijkowego zadziałało. Wszelkie dużo większe rozwiazania traktuję z rezerwą trochę ;)
@b3rly: Dlatego niewykluczone, że jak będzie potrzeba to skorzystam z podobnego rozwiązania. Póki co potencjalnie to się przyda osobie, która dziś stwierdziła, że chyba czytała kiedyś, że istnieje coś takiego jak Django, a nigdy nie pisała nic w pythonie ani nic webowego ;)