1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
|
.. _table_data:
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 :func:`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 your build uses tables to display `~django.db.models.query.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 `~.models.Field.verbose_name`
- Specialized columns are used where possible (e.g. `.DateColumn` for a
`~.models.DateField`)
When using this approach, the following options might be useful to customize
what fields to show or hide:
- `~.Table.Meta.sequence` -- reorder columns (if used alone, columns that are not specified are still rendered in the table after the specified columns)
- `~.Table.Meta.fields` -- specify model fields to *include*
- `~.Table.Meta.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 `~.Table.Meta.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 `~django.db.models.query.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.
|