Search code examples
djangodjango-tables2

How to create the Tables2 class dynamically


In the tables.py in the example dir there is:

class Bootstrap4Table(tables.Table):
    country = tables.Column(linkify=True)
    continent = tables.Column(accessor="country__continent", linkify=True)
    class Meta:
        model = Person
        template_name = "django_tables2/bootstrap4.html"
        attrs = {"class": "table table-hover"}
        exclude = ("friendly",)

I am trying to create a table class dynamically, so I did: Override the get_table method like so:

def get_table(self, **kwargs):
    """
    Return a table object to use. The table has automatic support for
    sorting and pagination.
    """
    table_class, table_data = type('QueryTable', (tables.Table), myTableCol), mylist
    table_class = table_class
    print(table_class, table_data)
    table = table_class(data=table_data, **kwargs)
    return RequestConfig(self.request, paginate=self.get_table_pagination(table)).configure(table)

Where the table_class, table_data is where I am creating the class. myTableCol provides the columns and mylist provides the data for each column. My problem is I dont know how to include the template_name = "django_tables2/bootstrap4.html" when I am dynamically creating the table class. Also, when i do it this way, the tables dont show any borders.

I am pulling data from a rdf graph and I don't know the name or number of columns, so I want to dynamically create the columns along with having the Meta class with template_name = "django_tables2/bootstrap4.html.


Solution

  • I figured it out by going through the /django_tables2/tables.py.

    So, I first created a Meta class to serve as the inner class to the class that I wanted to create:

    Meta = type('Meta', (object,), {'template_name':"django_tables2/bootstrap4.html", 'attrs':{"class": "paleblue"},})
    

    I then append this class to the myTableCol (I need to change the name) dictionary like myTableCol.update({'Meta':Meta}).

    Next, I created the class that I wanted:

    QueryTable2=type('QueryTable', (tables.Table,), myTableCol)
    

    The reason why I had to update the dictionary of the column names is that lines 34-39 in /django_tables2/tables.py of the DeclarativeColumnsMetaclass class loops over the attributes of the class and checks if the items in the myTableCol are instances of a Column. If true the key and value are appended to a list of dictionaries, if not they are added to a another dictionary as key/value pairs.

    So, I updated my get_table like:

    def get_table(self, **kwargs):
        """
        Return a table object to use. The table has automatic support for
        sorting and pagination.
        """
        ....
        other processing
        ....
    
        Meta = type('Meta', (object,), {'template_name':"django_tables2/bootstrap4.html", 'attrs':{"class": "paleblue"},})
        myTableCol.update({'Meta':Meta})
        QueryTable2=type('QueryTable', (tables.Table,), myTableCol)
        table_class, table_data =  QueryTable2, mylist
        table_class = table_class
        print(table_class, table_data)
        table = table_class(data=table_data, **kwargs)
        return RequestConfig(self.request, paginate=self.get_table_pagination(table)).configure(table)