Devido a toda a meta mágica acontecendo, estou usando atualmente:
class StatsTable(tables.Table):
class Meta:
orderable = False
attrs = {'class': 'tablesorter'}
def __init__(self, form, request, *args, **kwargs):
rf_values = form.get_values()
rf_annotations = form.get_annotations()
rf_filter = form.get_filter()
rf_calculations = form.get_calculations()
data = list(
HourlyStat.objects.filter(**rf_filter).values(*rf_values).annotate(**rf_annotations).order_by('-clicks')
)
super(StatsTable, self).__init__(data, *args, **kwargs)
columns = rf_values + rf_annotations.keys() + rf_calculations
for col in columns:
self.base_columns[col] = tables.Column()
realmente o único problema comigo usando-o assim é o fato de que eu não posso simplesmente chamar super() por último, ele tem que estar no meio. Eu acho que é porque a metaclasse não procura base_columns em si mesma, mas apenas em modelos herdados. Realmente isso parece muito mais confuso do que os self.fields nos formulários do django.
Isso é estranho
Eu adiciono colunas dinâmicas apenas anexando-as a self.base_columns:
self.base_columns['column_name'] = tables.Column()
Uma coisa que achei irritante é que, ao fazer isso, modifico o atributo class, não o atributo instance, então qualquer coluna que eu adicionar em uma solicitação será mostrada em todas as solicitações subsequentes à tabela, a solução para colunas dinâmicas reais que encontrei foi:
class ComponenteContableColumns(tables.Table):
"""Table that shows ComponentesContables as columns."""
a_static_columns = tables.Column()
def __init__(self, *args, **kwargs):
# Create a copy of base_columns to restore at the end.
self._bc = copy.deepcopy(self.base_columns)
# Your dynamic columns added here:
if today is 'monday':
self.base_columns['monday'] = tables.Column()
if today is 'tuesday':
self.base_columns['tuesday'] = tables.Column()
super().__init__(*args, **kwargs)
# restore original base_column to avoid permanent columns.
type(self).base_columns = self._bc
Eu tenho o mesmo problema que @jmfederico e tive que colocar seu hack sugerido (solução alternativa) no lugar. Existe uma sugestão melhor sobre como adicionar colunas dinamicamente a uma tabela? Eu tenho uma tabela com datas de uma consulta na parte superior, então, dependendo de como ela é filtrada, pode ter mais ou menos e datas diferentes. Eu não conseguia descobrir por que às vezes tínhamos algumas colunas extras que não estavam na consulta e descobrimos que era o mesmo problema.
Para referência aqui está minha classe de tabela
class ActivitySummaryTable(TableWithRawData):
activity = tables.Column(verbose_name=_('Activity'), orderable=False)
# the rest of the columns will be added based on the filter provided
def __init__(self, extra_cols, *args, **kwargs):
"""Pass in a list of tuples of extra columns to add in the format (colunm_name, column)"""
# Temporary hack taken from: https://github.com/bradleyayers/django-tables2/issues/70 to avoid the issue where
# we got the same columns from the previous instance added back
# Create a copy of base_columns to restore at the end.
_bc = copy.deepcopy(self.base_columns)
for col_name, col in extra_cols:
self.base_columns[col_name] = col
super(ActivitySummaryTable, self).__init__(*args, **kwargs)
# restore original base_column to avoid permanent columns.
type(self).base_columns = _bc
class Meta:
attrs = {'class': 'table'}
order_by = ('activity',)
Exemplo onde filtramos as datas e depois são adicionadas 2 datas perdidas no final
corrigido em 817d711 usando o argumento extra_columns
Comentários muito úteis
Isso é estranho
Eu adiciono colunas dinâmicas apenas anexando-as a self.base_columns:
Uma coisa que achei irritante é que, ao fazer isso, modifico o atributo class, não o atributo instance, então qualquer coluna que eu adicionar em uma solicitação será mostrada em todas as solicitações subsequentes à tabela, a solução para colunas dinâmicas reais que encontrei foi: