1👍
✅
I have a solution, but it’s not elegant.
I merge two dictionaries and build table for merged dictionary. After that i just add merged columns to the table. They are in same order as in merged dictionary. Also I’ve changed template for the table for handling merged columns.
Here is the code:
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)
And it’s a changed part of a template:
<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>
Source:stackexchange.com