我有一个解决方案,但它并不优雅。
我合并两个词典并为合并的词典构建表。之后,我只是将合并的列添加到表中。它们的顺序与合并字典中的顺序相同。我还更改了用于处理合并列的表格模板。
这是代码:
from collections import defaultdict
import django_tables2 as tables
def merge_table_dicts(labels, tables, key_column):
merged_tables = []
for table, label in zip(tables, labels):
new_table = []
for row in table:
new_row = {}
for key, value in row.iteritems():
if key == key_column:
new_row[key] = value
else:
new_row[old_key + '_' + label] = value
new_table.append(new_row)
merged_tables.append(new_table)
d = defaultdict(dict)
for l in merged_tables:
for elem in l:
d[elem[key_column]].update(elem)
merged_table_dicts = d.values()
return merged_table_dicts
def get_merged_table(labels, tables_dicts, key_column_name, merged_columns_order):
attrs = {}
# General options
class Meta:
order_by = (key_column_name,)
template = '_merged_table.html'
empty_text = 'No data presented'
attrs['Meta'] = Meta
attrs[key_column_name] = tables.Column()
for column in merged_columns_order:
for label in labels:
attrs[get_merged_key(column, label)] = tables.Column(verbose_name=label)
merged_table = type('MergedTable', (tables.Table,), attrs)
merged_columns = []
for merged_column_name in merged_columns_order:
column = tables.Column(verbose_name=merged_column_name,
attrs={"th": {"rowspan": len(labels)}})
merged_columns.append(column)
merged_table.merged_columns = merged_columns
# Merge data for table
data = merge_table_dicts(labels, tables_dicts, key_column_name)
return merged_table(data)
它是模板的更改部分:
<thead>
<tr>
{% with column=table.columns|first %}
{% if column.orderable %}
<th rowspan="2" {{ column.attrs.th.as_html }}><a href="{% querystring table.prefixed_order_by_field=column.order_by_alias.next %}">{{ column.header }}</a></th>
{% else %}
<th rowspan="2" {{ column.attrs.th.as_html }}>{{ column.header }}</th>
{% endif %}
{% endwith %}
{% for column in table.merged_columns %}
<th colspan="{{ column.attrs.th.rowspan }}">{{ column.header }}</th>
{% endfor %}
</tr>
<tr>
{% for column in table.columns %}
{% if not forloop.first %}
{% if column.orderable %}
<td {{ column.attrs.th.as_html }}><a href="{% querystring table.prefixed_order_by_field=column.order_by_alias.next %}">{{ column.header }}</a></td>
{% else %}
<td {{ column.attrs.th.as_html }}>{{ column.header }}</td>
{% endif %}
{% endif %}
{% endfor %}
</tr>
</thead>