Andre
Andre

Reputation: 647

django-tables2 updating attrs has no effect

I am using django + django-tables2. I want to add to each column of my tables a td-level attribute which contains its name (for later client side processing). The tables are based on models and aren't built column by column. Hence I don't have an opportunity to supply these attributes at the time I define the table.

I am trying to inject the attributes at a later stage using this piece of code:

def inject_data_names(table: tables.Table) -> tables.Table:
    for col_name, col in table.columns.items():
        col.attrs['td']['data'] = str(col_name)
        print(col.attrs)
    return table

However, it seems to have no effect, when run on an instance of a child of tables.Table. The print statement shows this:

{'class': 'paleblue table', 'th': {'class': 'id orderable'}, 'td': {'class': 'id'}}
{'class': 'paleblue table', 'th': {'class': 'description orderable'}, 'td': {'class': 'description'}}
{'class': 'paleblue table', 'th': {'class': 'orderable start'}, 'td': {'class': 'start'}}

As you can see, the "data" value seems to be missing. Using Python 3.6.1, latest Django and django-tables2. Any clues?

UPD: Looking at the source code, the method attrs in BoundColumn actually returns a copy of the dictionary, hence the update has no effect. The question is, what's the right way of making the changes I want?

Link: http://django-tables2.readthedocs.io/en/latest/_modules/django_tables2/columns/base.html#BoundColumn

Upvotes: 0

Views: 950

Answers (2)

Andre
Andre

Reputation: 647

Thanks to the developers of the library, there is now a working solution to my problem. It requires the version 1.9.0 or later of the package:

class Table(tables.Table):
    class Meta:
        attrs = {
           'td': {'data-name': lambda column: column.name}
        }

Further discussion on github: https://github.com/bradleyayers/django-tables2/issues/451

Upvotes: 2

matyas
matyas

Reputation: 2796

I am not too familiar with django-tables but I found that somebody recently added this feature to the library:

https://github.com/bradleyayers/django-tables2/issues/70

this is the testcase for the commit that adds the feature to dynamically add columns: github link

# coding: utf-8
from __future__ import absolute_import, unicode_literals

import django_tables2 as tables


def test_dynamically_adding_columns():
    '''
    When adding columns to self.base_columns, they are actually added to
    the class attribute `Table.base_columns`, and not to the instance
    attribute, `table.base_columns`
    issue #403
    '''
    data = [
        {'name': 'Adrian', 'country': 'Australia'},
        {'name': 'Adrian', 'country': 'Brazil'},
        {'name': 'Audrey', 'country': 'Chile'},
        {'name': 'Bassie', 'country': 'Belgium'},
    ]

    class MyTable(tables.Table):
        name = tables.Column()

    # this is obvious:
    assert list(MyTable(data).columns.columns.keys()) == ['name']

    assert list(MyTable(data, extra_columns=[
        ('country', tables.Column())
    ]).columns.columns.keys()) == ['name', 'country']

    # this new instance should not have the extra columns added to the first instance.
    assert list(MyTable(data).columns.columns.keys()) == ['name']

Upvotes: 0

Related Questions