Tables#
iommi tables makes it easy to create full featured HTML tables easily:
generates header, rows and cells
sorting
filtering
pagination
bulk edit
link creation
customization on multiple levels, all the way down to templates for cells
automatic rowspan
grouping of headers

The code for the example above:
Table(
auto__model=Album,
page_size=10,
)
Read the full documentation and the Cookbook for more.
Creating tables from models#
Say I have some model:
class Foo(models.Model):
a = models.IntegerField()
def __str__(self):
return f'Foo: {self.a}'
class Bar(models.Model):
b = models.ForeignKey(Foo, on_delete=models.CASCADE)
c = models.CharField(max_length=255)
Now I can display a list of Bar
in a table like this:
def my_view(request):
return Table(auto__model=Bar)
This automatically creates a table with pagination and sorting. If you pass
query_from_indexes=True
you will get filters for all the model fields
that have database indexes. This filtering system includes an advanced filter
language. See Queries for more on filtering.
Explicit tables#
You can also create tables explicitly:
def albums(request):
class AlbumTable(Table):
# Shortcut for creating checkboxes to select rows
select = Column.select()
name = Column()
# Show the name field from Artist. This works for plain old objects too.
artist_name = Column(
attr='artist__name',
# put this field into the query language
filter__include=True,
)
year = Column.number(
# Enable bulk editing for this field
bulk__include=True,
)
return AlbumTable(rows=Album.objects.all())
This gives me a view with filtering, sorting, bulk edit and pagination.
Table as CSV#
Tables are able to render as CSV files. This is enabled if there is specified a name to use on the resulting file,
as a value of the table parameter extra_evaluated__report_name
, and a file header name for each column that is
to be included, specified by the column parameter extra_evaluated__report_name
.
For example:
def albums(request):
class AlbumTable(Table):
class Meta:
extra_evaluated__report_name = 'Albums'
actions__download = Action(
attrs__href=lambda table, **_: '?' + table.endpoints.csv.endpoint_path,
)
name = Column(extra_evaluated__report_name='Name')
artist = Column(extra_evaluated__report_name='Artist')
year = Column.number(extra_evaluated__report_name='Artist')
return AlbumTable(rows=Album.objects.all())
This will behave like an ordinary table but when the csv rendering endpoint is invoked the content will be returned as a text file in CSV format.
Table of plain python objects#
def plain_objs_view(request):
# Say I have a class...
class Foo(object):
def __init__(self, i):
self.a = i
self.b = 'foo %s' % (i % 3)
self.c = (i, 1, 2, 3, 4)
# and a list of them
foos = [Foo(i) for i in range(4)]
# I can declare a table:
class FooTable(Table):
a = Column.number()
b = Column()
# Display the last value of the tuple
c = Column(
cell__format=lambda value, **_: value[-1],
)
# Calculate a value not present in Foo
sum_c = Column(
cell__value=lambda row, **_: sum(row.c),
sortable=False,
)
# now to get an HTML table:
return FooTable(rows=foos)
All these examples and a bigger example using many more features can be found in the examples project.