Django - Как сделать распаковку кортежа в шаблоне цикла for
-
06-07-2019 - |
Вопрос
В моем views.py я создаю список из двух кортежей, где вторым элементом в кортеже является другой список, например так:
[ Product_Type_1, [ product_1, product_2 ],
Product_Type_2, [ product_3, product_4 ]]
В простом старом Python я мог бы повторить список следующим образом:
for product_type, products in list:
print product_type
for product in products:
print product
Я не могу сделать то же самое в моем шаблоне Django:
{% for product_type, products in product_list %}
print product_type
{% for product in products %}
print product
{% endfor %}
{% endfor %}
Я получаю эту ошибку от Django:
При рендеринге возникла исключительная ситуация: аргумент zip # 2 должен поддерживать итерацию
Конечно, в шаблоне есть некоторая разметка HTML, а не операторы print. Разве распаковка кортежей не поддерживается на языке шаблонов Django? Или я иду по этому пути неправильно? Все, что я пытаюсь сделать, это отобразить простую иерархию объектов - есть несколько типов продуктов, каждый из которых имеет несколько продуктов (в models.py, Product имеет внешний ключ для Product_type, простого отношения «один ко многим»). р>
Очевидно, я совсем новичок в Django, поэтому любой вклад будет принят.
Решение
было бы лучше, если бы вы строили свои данные как {обратите внимание, что '(' и ')' можно соответственно заменить на '[' и ']', один для кортежей, один для списков}
[ (Product_Type_1, ( product_1, product_2 )),
(Product_Type_2, ( product_3, product_4 )) ]
и сделайте так, чтобы шаблон:
{% for product_type, products in product_type_list %}
{{ product_type }}
{% for product in products %}
{{ product }}
{% endfor %}
{% endfor %}
способ распаковки кортежей / списков для циклов основан на элементе, возвращаемом итератором списка. На каждой итерации возвращался только один элемент. первый раз в цикле, Product_Type_1, второй список продуктов ...
Другие советы
Другой способ заключается в следующем. Р>
Если у вас есть список кортежей, скажите:
mylst = [(a, b, c), (x, y, z), (l, m, n)]
тогда можно распаковать этот список в файле шаблона следующим образом. В моем случае у меня был список кортежей, который содержал URL, заголовок и резюме документа.
{% for item in mylst %}
{{ item.0 }} {{ item.1}} {{ item.2 }}
{% endfor %}
Вы должны использовать этот способ:
{% for product_type, products in product_list.items %}
print product_type
{% for product in products %}
print product
{% endfor %}
{% endfor %}
Не забывайте переменные элементы в данных словаря
Если у вас есть фиксированный номер в ваших кортежах, вы можете просто использовать индексацию. Мне нужно было смешать словарь, и значения были кортежами, поэтому я сделал это:
В виде:
my_dict = {'parrot': ('dead', 'stone'), 'lumberjack': ('sleep_all_night', 'work_all_day')}
В шаблоне:
<select>
{% for key, tuple in my_dict.items %}
<option value="{{ key }}" important-attr="{{ tuple.0 }}">{{ tuple.1 }}</option>
{% endfor %}
</select>
Просто отправьте шаблону список типов продуктов и выполните что-то вроде:
{% for product_type in product_type_list %}
{{ product_type }}
{% for product in product_type.products.all %}
{{ product }}
{% endfor %}
{% endfor %}
Прошло немного времени, поэтому я не могу точно вспомнить, каков синтаксис, дайте мне знать, если это работает. Ознакомьтесь с документацией .