Получить элемент списка динамически в шаблонах django
У меня есть некоторый цикл на странице и нужен элемент списка, зависящий от номера цикла.
Когда я звоню:
{{ mylist.1 }}
{{ mylist.2 }}
{{ mylist.3 }}
все работает отлично, но мне действительно нужно что-то вроде:
{% for x in somenumber|MyCustomRangeTag %}
{{ mylist.x }}
{% endfor %}
MyCustomRangeTag дает мне Python range()
он работает, и у меня уже есть x
как число. Таким образом, x
равно 1, 2, 3 и т.д. В зависимости от номера цикла.
Возможно ли это и как?
Ответы
Ответ 1
Это невозможно сразу, потому что Django считает, что "x"
является ключом к поиску в mylist
- вместо значения x. Итак, когда x = 5
, Django пытается искать mylist["x"]
вместо mylist[5]
.
Использовать следующий фильтр в качестве обходного пути:
@register.filter
def lookup(d, key):
return d[key]
и используйте его как
{{ mylist|lookup:x }}
Ответ 2
Я замечаю, что @e-satis упомянул об этом, но я думаю, что встроенный тег шаблона среза заслуживает некоторой любви.
{{ item | slice:"2" }} #gets the third element of the list
Ответ 3
В теге slice в шаблонах Django может использоваться код кусочка python, но синтаксис однозначно отличается. Например, если вы хотите получить элемент последовательности с переменной, в python вы должны написать что-то похожее на следующее:
>>>mylist = ["0th Element", "1th Element"]
>>>zero, one = 0, 1
>>>mylist[zero]
"0th Element"
>>>mylist[one]
"1th Element"
Использование этого синтаксиса с тегом шаблона slange Django вернет в каждом случае разреженный список сомнительной утилиты для получения элемента известного индекса:
{% with "0" as zero %}
{% with "1" as one %}
{% with "2" as two %}
{{mylist|slice:zero}} {{mylist|slice:one}} {{mylist|slice:two}}
{% endwith %}
{% endwith %}
{% endwith %}
Относится к html:
[] ["0th Element"] ["0th Element", "1th Element"]
Обратите внимание на отличия: вы получаете результат mylist[:x]
вместо mylist[x]
.
Django предоставляет достаточно инструментов для работы над этим. Первый трюк заключается в использовании явных фрагментов типа 0:1
для ваших индексов, а затем |join:""
результирующий список в один элемент. Например:
{% with "0:1" as zero %}
{{mylist|slice:zero|join:""}}
{% endwith %}
Урожайность:
0th Element
Это особенно удобно, если вам нужно получить доступ к индексу родительского цикла при работе с итерируемым внутри дочернего цикла:
{% for parent in parent_loop %}
{% cycle "0:1" "1:2" "2:3" as parent_loop_index silent %}
{% for child in child_loop %}
{{child|slice:parent_loop_index|join:""}}
{% endfor %}
{% endfor %}
Завершено только с запасными частями, хотя я не думаю, что Django уже реализовал достижения.
Ответ 4
Вы уверены, что не можете просто сделать:
{% for item in mylist %}
{{ item }}
{% endfor %}
С фильтром среза вы можете даже выполнить некоторую настройку.