3

I have a django-tables2 Table with many columns. Hence, I don't want to specify each column in the Table class separately, but just set the Model correspondingly.

Now, I'd like to change the properties of some columns that I can identify via their name. I'd like to do something like:

table = MyTable(my_queryset)

for col in table.columns.items():
    col_name = col[0]
    if col_name.endswith('some_suffix'):
        table.columns[col_name].attrs['td'].update({'align': 'right'})

... which was supposed to change all columns whose name end with 'some_suffix' such that the values are aligned right.

The problem, however, seems to be that table.columns[col_name] is a BoundColumn whose properties apparently can't be altered.

Does anyone know a quick fix for this problem ("make selected columns right aligned")?

Thank you, Philip

Phil
  • 43
  • 5

2 Answers2

1

I had a similar problem, not being able to change the attributes of the bound columns. This question seems to be the only one at SO to address this problem.

Besides table.columns there is also a property table.base_columns. In the second the columns aren't yet bound. So here is my approach:

import django_tables2 as tables

class YourTable(tables.Table)
    # define your columns

    # overload the init method
    def __init__(self, *args, **kwargs):
        for col in self.base_columns:
            if col[0].endswith('some_suffix'):
                col[1].attrs['td'].update({'align': 'right'})
        # very important! call the parent method
        super(YourTable, self).__init__(*args, **kwargs)

The changes now will be saved, because they are made in the base columns before they are bound. Calling the parent method - overloading the __init__ method - binds them and the changes are visible in the template.

cezar
  • 11,616
  • 6
  • 48
  • 84
0

I've found that the best way to do such things is to create the table dynamically (i.e create a Table class using pythons type and set its fields). I am describing this technique (to solve a different problem) in this article: http://spapas.github.io/2015/10/05/django-dynamic-tables-similar-models/

What I propose in that article, is to create a get_table_class method that will create the Table subclass. In your case, it could be something like this:

def get_table_class(model):
      def get_table_column(field):
          if field.name.endswith('some_suffix'):
              return tables.Column(attrs={"td": {"align": "right"}})
          else:
              return tables.Column()

      attrs = dict(
          (f.name, get_table_column(f)) for
          f in model._meta.fields if not f.name == 'id'
      )
      attrs['Meta'] = type('Meta', (), {'attrs':{"class":"table"}, "order_by": ("-created_on", ) } )
      klass = type('DTable', (tables.Table, ), attrs)

      return klass

The attrs = dict(...) line above creates a dictionary containing all the field names of the model that you pass to it (except the id field) as keys and corresponding Table columns (using your suffix check to align them through get_table_column) as values. The attrs['Meta'] = ... line adds a Meta to this dictionary (as you can see the model attribute is no longer needed) and finally the klass = type... line creates a Table subclass using the above dictionary!

Serafeim
  • 14,962
  • 14
  • 91
  • 133