Подтвердить что ты не робот

Получить элемент списка динамически в шаблонах django

У меня есть некоторый цикл на странице и нужен элемент списка, зависящий от номера цикла.

Когда я звоню:

{{ mylist.1 }}
{{ mylist.2 }}
{{ mylist.3 }}

все работает отлично, но мне действительно нужно что-то вроде:

{% for x in somenumber|MyCustomRangeTag %}
    {{ mylist.x }}
{% endfor %}

MyCustomRangeTag дает мне Python range() он работает, и у меня уже есть x как число. Таким образом, x равно 1, 2, 3 и т.д. В зависимости от номера цикла. Возможно ли это и как?

4b9b3361

Ответ 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 %}

С фильтром среза вы можете даже выполнить некоторую настройку.