【问题标题】:What's the correct way to print a matrix with labels in a Django template?在 Django 模板中打印带有标签的矩阵的正确方法是什么?
【发布时间】:2015-04-12 00:37:35
【问题描述】:

我想在 Django 中做一些非常简单的事情:将矩阵打印为 HTML 表格,并为行和列添加标签。这些是我认为的变量:

matrix = np.array([
    [101, 102, 103],
    [201, 202, 203],
])
colnames = ['Foo', 'Bar', 'Barf']
rownames = ['Spam', 'Eggs']

我想要一个如下所示的表格:

富吧酒吧 垃圾邮件 101 102 103 鸡蛋 201 202 203

我的模板代码如下所示:

<table>
    <tr>
        <th></th>
        {% for colname in colnames %}
            <th>{{ colname }}</th>
        {% endfor %}
    </tr>
    {% for rowname in rownames %}{% with forloop.counter0 as rowindex %}
        <tr>
            <th>{{ rowname }}</th>
            {% for colname in colnames %}{% with forloop.counter0 as colindex %}
                <td>TABLECELL</td>
            {% endwith %}{% endfor %}
        </tr>
    {% endwith %}{% endfor %}
</table>

TABLECELL 不同值的输出:

{{ rowindex }}, {{ colindex }} --> 带有索引的表    :)

{{ matrix.0.0 }} --> 满桌 101 :)

{{ matrix.rowindex.colindex }} --> 带有空单元格的表格 :(

由于前两件事情有效,假设最后一件事情会产生预期的结果似乎并不疯狂。我唯一的解释是 rowindexcolindex 可能是字符串——当然 int() 是 Django 模板中被禁止的许多内容之一。

有谁知道我怎样才能做到这一点?或者理想情况下: 有谁知道这是如何在 Django 中完成的?

编辑 1:

看来我必须将枚举列表传递给模板。我将它们提供为 enum_colnamesenum_rownames,但现在我什至无法执行嵌套的 for 循环:

<table>
    <tr>
        <th></th>
        {% for unused_colindex, colname in enum_colnames %}
            <th>{{ colname }}</th>
        {% endfor %}
    </tr>
    {% for rowindex, rowname in enum_rownames %}
        <tr>
            <th>{{ rowname }}</th>
            {% for doesnt_work_anyway in enum_colnames %}
                <td>You don't see me.</td>
            {% endfor %}
        </tr>
    {% endfor %}
</table>

这给出了一个表格,其中所有&lt;th&gt;s 都填充了正确的标签,但根本没有&lt;td&gt;s。

编辑 2:

我发现了一个非常丑陋的“解决方案”,我在这里发布它作为“有效”的示例,但显然不是我的问题的答案——这应该在 Django 中如何完成.来了:

derp = ['', 'Foo', 'Bar', 'Barf', 'Spam', 101, 102, 103, 'Eggs', 201, 202, 203]
iderp = enumerate(derp)
<table>
    {% for i, d in iderp %}
        {% if i < 4 %}  <!-- if top row: th -->
            {% cycle '<tr><th>' '<th>' '<th>' '<th>' %}
        {% else %}  <!-- else: td -->
            {% cycle '<tr><th>' '<td>' '<td>' '<td>' %}
        {% endif %}
            {{ d }}
        {% if i < 4 %}  <!-- if top row: th -->
            {% cycle '</th>' '</th>' '</th>' '</th></tr>' %}
        {% else %}  <!-- else: td -->
            {% cycle '</th>' '</th>' '</td>' '</td></tr>' %}
        {% endif %}
    {% endfor %}
</table>

注意它只能用于这种特定宽度的表格。所以在这种形式下,它甚至不是初始问题的真正解决方案。

【问题讨论】:

  • 关于编辑 2,如果您使用平面列表,您还需要将列数传递给模板。这就是为什么我建议使用与矩阵结构相同的表格。我现在添加了关于如何构建它的建议。如果使用模板的forloop.first,可以控制第一列是否为&lt;th&gt;
  • 让我们暂时忘记&lt;th&gt;&lt;td&gt; 的麻烦,假设我使用平面列表并将列数传递为width。然后我需要像{% cycle '&lt;tr&gt;&lt;th&gt;' (width-1)*'&lt;td&gt;' %} 这样的东西。存在吗?
  • 否,但您可以使用forloop.counter 来做您需要的事情。我没有多想,因为我同意你的观点,这是一个非常丑陋的解决方案。您对我在模板外构建表格的回答有疑问吗?
  • 在视图中构建表格从来都不是我的问题,但使用 Django 模板语言格式化 HTML 过去和现在都是。 forloop.first 是获得 &lt;th&gt;&lt;td&gt; 正确的一个很好的提示。我想我现在有一个实际的解决方案。

标签: django django-templates django-views nested-loops


【解决方案1】:

您的问题似乎是a feature request suggesting the use of iterables in the cycle tag 的一个很好的用例。然后你可以只在第一个&lt;td&gt; 中使用{% cycle rownames %}

不幸的是,据我所知,这是不可能的。我会将该逻辑从模板中移到视图中(或者,更可能是实用函数或模型方法,具体取决于具体情况),构建一个易于在模板中处理的列表:

table = [
    ['Spam', 101, 102, 103],
    ['Eggs', 201, 202, 203],
]

建表的函数可能如下所示:

def build_table(rownames, matrix):
    table = []
    for rowname, values in zip(rownames, matrix):
        row = [rowname]
        row.extend(values.tolist())
        table.append(row)
    return table

【讨论】:

    【解决方案2】:

    感谢 Paulo Almeida 在他的回答中提供了两个基本提示:

    • 应在视图中构建表格(包括标签)。

    • forloop.first可用于将标签放入&lt;th&gt;s。

    table = [
        ['', 'Foo', 'Bar', 'Barf'],
        ['Spam', 101, 102, 103],
        ['Eggs', 201, 202, 203],
    ]
    
    <table>
        {% for row in table %}
            <tr>
            {% for cell in row %}
                {% if forloop.first or forloop.parentloop.first %} <th> {% else %} <td> {% endif %}
                    {{ cell }}
                {% if forloop.first or forloop.parentloop.first %} </th> {% else %} </td> {% endif %}
            {% endfor %}
            </tr>
        {% endfor %}
    </table>
    

    我猜我的隐含问题(如何从模板访问多维数组的值)的答案是这是不可能的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-17
      • 2011-11-24
      相关资源
      最近更新 更多