Custom rendering¶
Various options are available for changing the way the table is rendered. Each approach has a different balance of ease-of-use and flexibility.
Table.render_FOO()
methods¶
To change how a column is rendered, implement a render_FOO
method on the
table (where FOO
is the column name). This approach is suitable if
you have a one-off change that you don’t want to use in multiple tables.
Supported keyword arguments include:
record
– the entire record for the row from the table datavalue
– the value for the cell retrieved from the table datacolumn
– theColumn
objectbound_column
– theBoundColumn
objectbound_row
– theBoundRow
objecttable
– alias forself
Here’s an example where the first column displays the current row number:
>>> import django_tables2 as tables
>>> import itertools
>>> class SimpleTable(tables.Table):
... row_number = tables.Column(empty_values=())
... id = tables.Column()
... age = tables.Column()
...
... def __init__(self, *args, **kwargs):
... super(SimpleTable, self).__init__(*args, **kwargs)
... self.counter = itertools.count()
...
... def render_row_number(self):
... return 'Row %d' % next(self.counter)
...
... def render_id(self, value):
... return '<%s>' % value
...
>>> table = SimpleTable([{'age': 31, 'id': 10}, {'age': 34, 'id': 11}])
>>> for cell in table.rows[0]:
... print cell
...
Row 0
<10>
31
Python’s inspect.getargspec
is used to only pass the arguments declared by the
function. This means it’s not necessary to add a catch all (**
) keyword
argument.
Important
render
methods are only called if the value for a cell is determined to
be not an empty value. When a value is in Column.empty_values
,
a default value is rendered instead (both Column.render
and
Table.render_FOO
are skipped).
Subclassing Column
¶
Defining a column subclass allows functionality to be reused across tables.
Columns have a render
method that behaves the same as Table.render_FOO() methods
methods on tables:
>>> import django_tables2 as tables
>>>
>>> class UpperColumn(tables.Column):
... def render(self, value):
... return value.upper()
...
>>> class Example(tables.Table):
... normal = tables.Column()
... upper = UpperColumn()
...
>>> data = [{'normal': 'Hi there!',
... 'upper': 'Hi there!'}]
...
>>> table = Example(data)
>>> # renders to something like this:
'''<table>
<thead><tr><th>Normal</th><th>Upper</th></tr></thead>
<tbody><tr><td>Hi there!</td><td>HI THERE!</td></tr></tbody>
</table>'''
See Table.render_FOO() methods for a list of arguments that can be accepted.
For complicated columns, you may want to return HTML from the
render()
method. Make sure to use Django’s html formatting functions:
>>> from django.utils.html import format_html
>>>
>>> class ImageColumn(tables.Column):
... def render(self, value):
... return format_html('<img src="/media/img/{}.jpg" />', value)
...
CSS¶
In order to use CSS to style a table, you’ll probably want to add a
class
or id
attribute to the <table>
element. django-tables2 has
a hook that allows arbitrary attributes to be added to the <table>
tag.
>>> import django_tables2 as tables
>>>
>>> class SimpleTable(tables.Table):
... id = tables.Column()
... age = tables.Column()
...
... class Meta:
... attrs = {'class': 'mytable'}
...
>>> table = SimpleTable()
>>> # renders to something like this:
'<table class="mytable">...'