在 Django 模板中打印带有标签的矩阵的正确方法是什么?
What's the correct way to print a matrix with labels in a Django template?
我想在 Django 中做一些非常简单的事情:将矩阵打印为 HTML table,并为行和列添加标签。这些是我认为的变量:
matrix = np.array([
[101, 102, 103],
[201, 202, 203],
])
colnames = ['Foo', 'Bar', 'Barf']
rownames = ['Spam', 'Eggs']
我想要一个看起来像这样的 table:
Foo 酒吧酒吧
垃圾邮件 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 }}
--> table 带有索引 :)
{{ matrix.0.0 }}
--> table 全是 101 :)
{{ matrix.rowindex.colindex }}
--> table 单元格为空 :(
由于前两件事有效,假设最后一件会产生预期结果似乎并不疯狂。我唯一的解释是 rowindex
和 colindex
可能是字符串——当然 int()
是 Django 模板中禁止的许多内容之一。
有谁知道我该怎么做?或者理想情况下:
有谁知道这是如何在 Django 中完成的?
编辑 1:
看来我必须将枚举列表传递给模板。我将它们提供为 enum_colnames
和 enum_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>
这给出了一个 table,其中所有 <th>
都填充了正确的标签,但根本没有 <td>
。
编辑 2:
我发现了一个非常丑陋的 "solution",我将其发布在这里作为 "works" 的示例,但显然不是我问题的答案 — 应该如何 在 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>
请注意它如何只能用于此特定宽度的 tables。所以在这种形式下,它甚至不是最初问题的真正解决方案。
您的问题似乎是 a feature request suggesting the use of iterables in the cycle tag 的一个很好的用例。然后你可以在第一个 <td>
.
中 {% cycle rownames %}
不幸的是,据我所知,这是不可能的。我会将该逻辑从模板中取出并放入视图中(或者更可能是实用函数或模型方法,具体取决于具体情况),构建一个易于在模板中处理的列表:
table = [
['Spam', 101, 102, 103],
['Eggs', 201, 202, 203],
]
构建 table 的函数可能如下所示:
def build_table(rownames, matrix):
table = []
for rowname, values in zip(rownames, matrix):
row = [rowname]
row.extend(values.tolist())
table.append(row)
return table
感谢 Paulo Almeida 在他的回答中提供了两个重要提示:
table — 包括标签 — 应该在视图中构建。
forloop.first
可用于将标签放在 <th>
秒内。
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>
我想我隐含的问题——如何从模板访问多维数组的值——的答案是这是不可能的。
我想在 Django 中做一些非常简单的事情:将矩阵打印为 HTML table,并为行和列添加标签。这些是我认为的变量:
matrix = np.array([
[101, 102, 103],
[201, 202, 203],
])
colnames = ['Foo', 'Bar', 'Barf']
rownames = ['Spam', 'Eggs']
我想要一个看起来像这样的 table:
Foo 酒吧酒吧 垃圾邮件 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 }}
--> table 带有索引 :)
{{ matrix.0.0 }}
--> table 全是 101 :)
{{ matrix.rowindex.colindex }}
--> table 单元格为空 :(
由于前两件事有效,假设最后一件会产生预期结果似乎并不疯狂。我唯一的解释是 rowindex
和 colindex
可能是字符串——当然 int()
是 Django 模板中禁止的许多内容之一。
有谁知道我该怎么做?或者理想情况下: 有谁知道这是如何在 Django 中完成的?
编辑 1:
看来我必须将枚举列表传递给模板。我将它们提供为 enum_colnames
和 enum_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>
这给出了一个 table,其中所有 <th>
都填充了正确的标签,但根本没有 <td>
。
编辑 2:
我发现了一个非常丑陋的 "solution",我将其发布在这里作为 "works" 的示例,但显然不是我问题的答案 — 应该如何 在 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>
请注意它如何只能用于此特定宽度的 tables。所以在这种形式下,它甚至不是最初问题的真正解决方案。
您的问题似乎是 a feature request suggesting the use of iterables in the cycle tag 的一个很好的用例。然后你可以在第一个 <td>
.
{% cycle rownames %}
不幸的是,据我所知,这是不可能的。我会将该逻辑从模板中取出并放入视图中(或者更可能是实用函数或模型方法,具体取决于具体情况),构建一个易于在模板中处理的列表:
table = [
['Spam', 101, 102, 103],
['Eggs', 201, 202, 203],
]
构建 table 的函数可能如下所示:
def build_table(rownames, matrix):
table = []
for rowname, values in zip(rownames, matrix):
row = [rowname]
row.extend(values.tolist())
table.append(row)
return table
感谢 Paulo Almeida 在他的回答中提供了两个重要提示:
table — 包括标签 — 应该在视图中构建。
forloop.first
可用于将标签放在<th>
秒内。
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>
我想我隐含的问题——如何从模板访问多维数组的值——的答案是这是不可能的。