【问题标题】:Django - How to do tuple unpacking in a template 'for' loopDjango - 如何在模板“for”循环中进行元组解包
【发布时间】:2010-09-21 05:28:21
【问题描述】:

在我的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 标记,而不是打印语句。 Django 模板语言不支持元组解包吗?还是我以错误的方式解决这个问题?我要做的只是显示一个简单的对象层次结构 - 有几种产品类型,每种都有几个产品(在 models.py 中,Product 有一个 Product_type 的外键,一个简单的一对多关系)。

显然,我对 Django 还是很陌生,因此我们将不胜感激。

【问题讨论】:

  • 您谈论元组,但您的问题仅包含列表。它们在 python 中是不同的东西。
  • 你实际上没有二元组。仔细查看您的列表,您有 4 个列表项。正如 Jonny Buchanan 所说,您需要这样做: [ [Product_Type_1, [ product_1, product_2 ], ], [Product_Type_2, [ product_3, product_4 ], ], ] 以获得二元组的列表版本。

标签: python django templates tuples iterable-unpacking


【解决方案1】:

另一种方式如下。

如果有一个元组列表说:

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

然后可以通过以下方式在模板文件中解压缩此列表。 在我的例子中,我有一个包含 URL、标题和文档摘要的元组列表。

{% for item in mylst %}    
     {{ item.0 }} {{ item.1}} {{ item.2 }}    
{% endfor %}

【讨论】:

  • .0 ... 一点也不直观。
  • @iuliux 的诀窍是记住模板语言使. 意味着从变量访问到订阅,通过方法调用,所有这些都使用相同的语法......仍然同意你的观点,虽然: )
  • 那里为什么有正斜杠\?
【解决方案2】:

如果你像{注意'('和')'可以分别交换'['和']',一个用于元组,一个用于列表}

[ (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 %}

元组/列表在 for 循环中解包的方式基于列表迭代器返回的项目。 每次迭代只返回一项。第一次循环,Product_Type_1,第二次你的产品列表......

【讨论】:

  • 即您以为您正在构建一个二元组列表,但您忘记了元组部分 - 请注意 Cipher 答案中产品类型/产品列表对周围的额外括号
  • 这不适用于较旧的 Django 版本(如 GAE 中使用的版本)。如果您收到此错误,请使用 Ashwin Rao 的答案:“ 'for' statements with 5 words should end in 'reversed'”
【解决方案3】:

你必须这样使用:

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

不要忘记字典数据中的变量项

【讨论】:

  • 最后,我正在寻找的答案。谢谢!
【解决方案4】:

如果你的元组中有一个固定的数字,你可以只使用索引。我需要混合字典并且值是元组,所以我这样做了:

在视图中:

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>

【讨论】:

    【解决方案5】:

    只需向模板发送产品类型列表并执行以下操作:

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

    已经有一段时间了,所以我不记得确切的语法是什么,让我知道它是否有效。检查documentation。

    【讨论】:

    • Chris Lawlor 没有解释他是如何得到他所拥有的数据结构的(这实际上不是二元组列表),但是这种建议的方法会导致显示 N + 1 个查询产品列表。
    • 这里是龙。使用此建议,您将为每个 product_type 单独访问数据库。我怀疑最小化数据库负载可能是首先使用元组的动机。
    • 我认为您可以使用 select_related() 来减轻这种特殊担忧,对吧?
    猜你喜欢
    • 2012-06-27
    • 2013-10-26
    • 1970-01-01
    • 2012-06-07
    • 1970-01-01
    • 1970-01-01
    • 2012-07-25
    • 2021-10-17
    • 2021-04-01
    相关资源
    最近更新 更多