# 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.

Note

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"
        else:
            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: record.pk
            }

will render tables with the following `<tr>` tag

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