Column and row attributes

Column attributes

Column attributes can be specified using the dict with specific keys. The dict defines HTML attributes for one of more elements within the column. Depending on the column, different elements are supported, however th, td, and cell are supported universally:

>>> import django_tables2 as tables
>>> class SimpleTable(tables.Table):
...     name = tables.Column(attrs={"th": {"id": "foo"}})
>>> # will render something like this:
'{snip}<thead><tr><th id="foo">{snip}<tbody><tr><td>{snip}'

Have a look at each column’s API reference to find which elements are supported.

If you need to add some extra attributes to column’s tags rendered in the footer, use key name tf, as described in section on CSS.

Callables passed in this dict will be called, with optional kwargs table, bound_column record and value, with the return value added. For example:

class Table(tables.Table):
    person = tables.Column(attrs={
        "td": {
            "data-length": lambda value: len(value)

will render the <td>’s in the tables <body> with a data-length attribute containing the number of characters in the value.


The keyword arguments record and value only make sense in the context of a row containing data. If you supply a callable with one of these keyword arguments, it will not be executed for the header and footer rows.

If you also want to customize the attributes of those tags, you must define a callable with a catchall (**kwargs) argument:

def data_first_name(**kwargs):
    first_name = kwargs.get("value", None)
    if first_name is None:
        return "header"
        return first_name

class Table(tables.Table):
    first_name = tables.Column(attrs={
        "td": {
            'data-first-name': data_first_name

This attrs can also be defined when subclassing a column, to allow better reuse:

class PersonColumn(tables.Column):
    attrs = {
        "td": {
            "data-first-name": lambda record: record.first_name
            "data-last-name": lambda record: record.last_name
    def render(self, record):
        return f"{record.first_name} {record.last_name}""

class Table(tables.Table):
    person = PersonColumn()

is equivalent to the previous example.

Row attributes

Row attributes can be specified using a dict defining the HTML attributes for the <tr> element on each row.

By default, class names odd and even are supplied to the rows, which can be customized using the row_attrs Table.Meta attribute or as argument to the constructor of Table. String-like values will just be added, callables will be called with optional keyword arguments record and table, the return value will be added. For example:

class Table(tables.Table):
    class Meta:
        model = User
        row_attrs = {
            "data-id": lambda record:

will render tables with the following <tr> tag

<tr class="odd" data-id="1"> [...] </tr>
<tr class="even" data-id="2"> [...] </tr>