Django - Как сделать распаковку кортежа в шаблоне цикла for

StackOverflow https://stackoverflow.com/questions/271077

Вопрос

В моем 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 %}

Прошло немного времени, поэтому я не могу точно вспомнить, каков синтаксис, дайте мне знать, если это работает. Ознакомьтесь с документацией .

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top