Closed coler-j closed 11 months ago
Seems like there should be some helpers for this. I ended up doing something like this:
column_data = copy.deepcopy(pivot_table_data)
for d in column_data:
del d['row_index_key']
sorted_column_keys = sorted(list(set().union(*(d.keys() for d in column_data))), reverse=True)
Then in the template:
<table>
<thead>
<tr>
<th>Name</th>
{% for key in column_keys %}
<th>{{ key }}</th>
{% endfor %}
</tr>
</thead>
<tbody>
{% for row in pivot_table %}
<tr>
<td>{{ row.row_index_key }}</td>
{% for key in column_keys %}
<td>{{ row|get_item:key }}</td>
{% endfor %}
</tr>
{% endfor %}
</tbody></table>
Where get_item
is a template filter to get a value from a dict (the row) by key.
It would be great if the result of the pivot table call could be fed into django-tables2 somehow. Any idea if/how this could be possible?
The result of the pivot table call is a values queryset with annotations or a list of dictionaries. The django-pivot library is not opinionated on what you do with this result, how you choose to render it on a template or process the data.
This can be fed into any library that handles querysets or lists of dictionaries. django-tables2 handles both just fine. You have to define a custom Table
because django-tables2 uses the fields on the model by default. But, taking the first example from the django-pivot readme:
import django_tables as tables
pivot_table = pivot(ShirtSales, 'shipped', 'region', 'units')
class PivotTable(tables.Table):
west = tables.Column()
east = tables.Column()
north = tables.Column()
south = tables.Column()
shipped = tables.DateColumn()
class Meta:
model = ShirtSales
pivot_table = PivotTable(pivot_table)
And then in your template
{% load render_table from django_tables2 %}
{% render_table pivot_table %}
You can read the django-tables2 docs for how to customize rendering this.
This would be great, except that I don't know the columns in advance. Just like in the django-pivot readme where the columns are dates. It is unknown in advance what date columns the pivot table will get. I will have a look if I can find another django table renderer that does not require to define the columns in advance.
I also would like to be able to feed the results of pivot
into django-tables2
but don't know my columns ahead of time.
Here is a work around that I worked up using the extra_columns
parameter of the tables.Table
constructor:
import django_tables as tables
class MyTable(tables.Table):
static_column = tables.Column()
pivot_table = pivot(ShirtSales, 'shipped', 'region', 'units')
cols = [(k, tables.Column()) for k,v in pivot_table[0].items()]
mytable = MyTable(data=pivot_table, extra_columns=cols)
The mytable
object is a tables2 table ready for rendering.
@ReedJessen Sounds great. I am going to try that. Just to be sure is holdings_pivot
the same variable as pivot_table
? And is cols
the same variable as dynamic_cols
?
Thanks
@jaspercram, ah, good catch. You're right. Sorry, I updated to be consistent in the snippet above.
I tried it and it works indeed. The only problem I still have is that it adds the extra column static_column
. And for the record, when using django-tables2
, the code should be slightly different:
import django_tables2 as tables, columns
class MyTable(tables.Table):
static_column = columns.Column()
pivot_table = pivot(ShirtSales, 'shipped', 'region', 'units')
cols = [(k, columns.Column()) for k,v in pivot_table[0].items()]
mytable = MyTable(data=pivot_table, extra_columns=cols)
@jaspercram can you plz elaborate more on where did you put the code? in Views.py or tables.py? I am having trouble figuring out how to pass a simple pivot_table to django tables and render that.
@hsaade-algo I think this code should be in the view, because you need data to create pivot_table
and you need pivot_table
to create instance of MyTable
. You can put MyTable
to your tables.py.
As per title, what is the best/easiest way to render the columns of the pivot table dynamically?