Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Intuitive way to dynamically add columns #70

Closed
blite opened this issue Apr 17, 2012 · 3 comments
Closed

Intuitive way to dynamically add columns #70

blite opened this issue Apr 17, 2012 · 3 comments

Comments

@blite
Copy link

blite commented Apr 17, 2012

Due to all the meta magic going on, I am currently using:

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()     

really the only issue with me using it like this is the fact that I can't simply call super() last it has to be in the middle. I guess its because the meta class doesn't actually look for base_columns on itself but only on inherited models. Really this just seems way messier than the self.fields on django forms.

@jmfederico
Copy link

This is odd
I add dynamic columns by just appending them to self.base_columns:

self.base_columns['column_name'] = tables.Column()

One thing I found annoying is that by doing that, I modify the class attribute, not the instance attribute, so any column I add on a request, will be shown on every subsequent request to the table, the solution to real dynamic columns I found was:

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

@intiocean
Copy link
Contributor

intiocean commented Dec 19, 2016

I have the same issue as @jmfederico and have had to put his suggested hack (workaround) in place. Is there a better suggestion on how to dynamically add columns to a table? I have a table with dates from a query along the top so depending on how it is filtered it may have more or less and different dates. I couldn't work out for the life of me why sometimes we had some extra columns that weren't in the query and figured out it was this same problem.

For reference here is my table class

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',)

Example where we filter the dates and then there are 2 stray dates added at the end
image

@jieter
Copy link
Owner

jieter commented May 24, 2017

fixed in 817d711 using the extra_columns argument

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants