Django-tables2: Provide a list of dictionary, how to generate a column for each dictionary entry

2.2k views Asked by At

I know if we have a model class, we can make a generate table and use:

class Meta:
    model = MyModel

To display every field.

Now say if I have a list of dictionaries, instead of model, is there a similar way to do so?

(Since there are so many different dictionaries, which might be dynamically created, I don't wanna create a customized one each time :-))

3

There are 3 answers

0
kviktor On

You can create your own class that inherits from Table and define the fields you want there.

class JsonTable(Table):
    json_key_1 = Column()
    json_key_2 = Column()

Also django tables2 have a fields attribute but you can't use it if your data is an array of dicts.

1
JL Peyret On

I've been doing this too, here's a rough sketch.

Piggy-backing on top of django_tables2 is miles ahead of rolling your own!

Plus, I hook up the results to jquery FooTable plugin.

    import django_tables2 as tables
    counter = 0

    def generate(li_dict):

        #unique classname.
        global counter
        counter += 1
        table_classname = "MyTableClass%s" % (counter)

        class Meta:
            #ahhh... Bootstrap
            attrs = {"class": "table table-striped"}

        #generate a class dynamically
        cls = type(table_classname,(tables.Table,),dict(Meta=Meta))

        #grab the first dict's keys
        li = li_dict[0].keys()

        for colname in li:
            column = tables.Column()
            cls.base_columns[colname] = column

        return cls

    #now, to make use of it...
    li_dict = [dict(a=11,b=12,c=13),dict(a=21,b=22,c=23)]

    cls = generate(li_dict)
    table = cls(li_dict)

    # below didn't work, wanted a whole bunch of django setup done first.
    # but I fairly confident it would...

    print table.as_html()
    >>>django.core.exceptions.ImproperlyConfigured: {% querystring %} requires django.core.context_processors.request to be in your settings.TEMPLATE_CONTEXT_PROCESSORS in order for the included template tags to function correctly.

    #this did...
    print "%s" % table

    >>><django_tables2.tables.MyTableClass1 object at 0x1070e1090>
0
Jeferson Souza Santos On

i am sorry for poor english :), but a think which can help, actually with this we can transforme a numpy (matrix) in a generic django table2. By the way, thanks Pyeret for your help.

def convert_array_list_dict(arr):
    _list = []
    for i in xrange(0, arr.shape[0]):
        _list.append(dict(enumerate(arr[i,:])))

    for i in xrange(0,len(_list)):

        for key in _list[i].keys():
            _list[i]["col_" + str(key)] = _list[i].pop(key)

    return _list`

This function above convert numpy array to list of dict

    counter = 0
def list_dict(dict_):
    global counter
    counter += 1
    table_classname = "MyTableClass%s" % (counter)

    class Meta:
        attrs = {"class": "paleblue", 'width': '150%'}

    cls = type(table_classname, (tables.Table,), dict(Meta=Meta))

    list_ = dict_[0].keys()

    for colname in list_:
        column = tables.Column()
        cls.base_columns[colname] = column

    return cls

This code make a generic table...and

t = np.loadtxt(doc.document)

tab = convert_array_list_dict(t)

table = list_dict(tab)


table_content = table(tab)
RequestConfig(request, paginate={'per_page': 30}).configure(table_content)
return render(request,'app/snippets/upload_file.html',{'document':document,'table_content':table_content})

Above we can see how use all code...