Django - Как сделать распаковку кортежа в шаблоне цикла for - PullRequest
54 голосов
/ 07 ноября 2008

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

Я получаю эту ошибку от Джанго:

При рендеринге возникла исключительная ситуация: аргумент zip # 2 должен поддерживать итерацию

Конечно, в шаблоне есть некоторая разметка HTML, а не операторы print. Разве распаковка кортежей не поддерживается на языке шаблонов Django? Или я иду по этому пути неправильно? Все, что я пытаюсь сделать, это отобразить простую иерархию объектов - есть несколько типов продуктов, каждый из которых имеет несколько продуктов (в models.py, Product имеет внешний ключ для Product_type, простого отношения один ко многим).

Очевидно, что я совсем новичок в Django, поэтому любой вклад будет принят.

Ответы [ 5 ]

73 голосов
/ 21 января 2011

Другой способ заключается в следующем.

Если есть список кортежей, скажите:

mylst = [(a, b, c), (x, y, z), (l, m, n)]

тогда можно распаковать этот список в файле шаблона следующим образом. В моем случае у меня был список кортежей, который содержал URL, заголовок и резюме документа.

{% for item in mylst %}    
     {{ item.0 }} {{ item.1}} {{ item.2 }}    
{% endfor %}
63 голосов
/ 07 ноября 2008

было бы лучше, если бы вы строили свои данные, как {обратите внимание, что '(' и ')' можно заменить на '[' и ']' соответственно, один для кортежей, один для списков}

[ (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, второй ваш список продуктов ...

5 голосов
/ 23 июля 2009

Вы должны использовать этот способ:

{% for product_type, products in product_list.items %}
    print product_type
    {% for product in products %}
        print product
    {% endfor %}
{% endfor %}

Не забывайте переменные элементы в словарных данных

3 голосов
/ 19 февраля 2016

Если у вас есть фиксированный номер в ваших кортежах, вы можете просто использовать индексацию. Мне нужно было смешать словарь, и значения были кортежами, поэтому я сделал это:

По виду:

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>
2 голосов
/ 07 ноября 2008

Просто отправьте шаблону список типов продуктов и сделайте что-то вроде:

{% for product_type in product_type_list %}
    {{ product_type }}
    {% for product in product_type.products.all %}
        {{ product }}
    {% endfor %}
{% endfor %}

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

...