Populating a table with data

Tables can be created from a range of input data structures. If you have seen the tutorial you will have seen a QuerySet being used, however any iterable that supports len() and contains items that exposes key-based access to column values is fine.

List of dicts

In an example we will demonstrate using list of dicts. When defining a table it is necessary to declare each column:

import django_tables2 as tables

data = [
    {"name": "Bradley"},
    {"name": "Stevie"},
]

class NameTable(tables.Table):
    name = tables.Column()

table = NameTable(data)

QuerySets

If you build use tables to display QuerySet data, rather than defining each column manually in the table, the Table.Meta.model option allows tables to be dynamically created based on a model:

# models.py
from django.contrib.auth import get_user_model
from django.db import models

class Person(models.Model):
    first_name = models.CharField(max_length=200)
    last_name = models.CharField(max_length=200)
    user = models.ForeignKey(get_user_model(), null=True, on_delete=models.CASCADE)
    birth_date = models.DateField()

# tables.py
import django_tables2 as tables

class PersonTable(tables.Table):
    class Meta:
        model = Person

# views.py
def person_list(request):
    table = PersonTable(Person.objects.all())

    return render(request, "person_list.html", {
        "table": table
    })

This has a number of benefits:

  • Less repetition

  • Column headers are defined using the field’s verbose_name

  • Specialized columns are used where possible (e.g. DateColumn for a DateField)

When using this approach, the following options might be useful to customize what fields to show or hide:

  • sequence – reorder columns (if used alone, columns that are not specified are still rendered in the table after the specified columns)

  • fields – specify model fields to include

  • exclude – specify model fields to exclude

These options can be specified as tuples. In this example we will demonstrate how this can be done:

# tables.py
class PersonTable(tables.Table):
    class Meta:
        model = Person
        sequence = ("last_name", "first_name", "birth_date", )
        exclude = ("user", )

With these options specified, the columns would be show according to the order defined in the sequence, while the user column will be hidden.

Performance

Django-tables tries to be efficient in displaying big datasets. It tries to avoid converting the QuerySet instances to lists by using SQL to slice the data and should be able to handle datasets with 100k records without a problem.

However, when performance is degrading, these tips might help:

  1. For large datasets, try to use LazyPaginator.

  2. Try to strip the table of customizations and check if performance improves. If so, re-add them one by one, checking for performance after each step. This should help to narrow down the source of your performance problems.