Various options are available for changing the way the table is rendered. Each approach has a different balance of ease-of-use and flexibility.
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:
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).
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)
...
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">...'