django-tables2 - An app for creating HTML tables
django-tables2 turns data into HTML tables. Features:
- Pagination
- Ordering
- Extendable
- Class based view
- Supports for queryset and list data
- Themes
Report bugs at http://github.com/bradleyayers/django-tables2/issues
Tutorial
- pip install django-tables2
- Add 'django_tables2' to INSTALLED_APPS
- Add 'django.core.context_processors.request' to TEMPLATE_CONTEXT_PROCESSORS
We’re going to run through creating a tutorial app. Let’s start with a simple model:
# tutorial/models.py
class Person(models.Model):
name = models.CharField(verbose_name="full name")
Add some data so you have something to display in the table. Now write a view to pass a Personqueryset into a template:
# tutorial/views.py
from django.shortcuts import render
def people(request):
return render(request, "people.html", {"people": Person.objects.all()})
Finally, implement the template:
{# tutorial/templates/people.html #}
{% load render_table from django_tables2 %}
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="{{ STATIC_URL }}django_tables2/themes/paleblue/css/screen.css" />
</head>
<body>
{% render_table people %}
</body>
</html>
Hook the view up in your URLs, and load the page, you should see:
![An example table rendered using django-tables2](https://i-blog.csdnimg.cn/blog_migrate/5c7c67d67cc2a476464b9c0c714aff28.png)
While simple, passing a queryset directly to {% render_table %} doesn’t allow for any customisation. For that, you must define a Table class.
# tutorial/tables.py
import django_tables2 as tables
from tutorial.models import Person
class PersonTable(tables.Table):
class Meta:
model = Person
# add class="paleblue" to <table> tag
attrs = {"class": "paleblue"}
You’ll then need to instantiate and configure the table in the view, before adding it to the context.
# tutorial/views.py
from django.shortcuts import render
from django_tables2 import RequestConfig
from tutorial.models import Person
from tutorial.tables import PersonTable
def people(request):
table = PersonTable(Person.objects.all())
RequestConfig(request).configure(table)
return render(request, 'people.html', {'table': table})
Using RequestConfig automatically pulls values from request.GET and updates the table accordingly. This enables data ordering and pagination.
Rather than passing a queryset to {% render_table %}, instead pass the table.
{% render_table table %}
Note
{% render_table %} works best when it’s used in a template that contains the current request in the context as request. The easiest way to enable this, is to ensure that theTEMPLATE_CONTEXT_PROCESSORS setting contains "django.core.context_processors.request".
At this point you haven’t actually customised anything, you’ve merely added the boilerplate code that {% render_table %} does for you when given a queryset. The remaining sections in this document describe how to change various aspects of the table.
Populating a table with data
Tables are compatible with a range of input data structures. If you’ve seen the tutorial you’ll have seen a queryset being used, however any iterable that supports len() and contains items that expose key-based accessed to column values is fine.
An an example we’ll demonstrate using list of dicts. When defining a table it’s necessary to declare each column. If your data matches the fields in a model, columns can be declared automatically for you via the Table.Meta.model option, but for non-queryset data you’ll probably want to declare them manually:
import django_tables2 as tables
data = [
{"name": "Bradley"},
{"name": "Stevie"},
]
class NameTable(tables.Table):
name = tables.Column()
table = NameTable(data)
You can use this technique to override columns that were automatically created viaTable.Meta.model too:
# models.py
from django.db import models
class Person(models.Model):
name = models.CharField(max_length=200)
# tables.py
import django_tables2 as tables
from .models import Person
class PersonTable(tables.Table):
name = tables.Column(verbose_name="full name")
class Meta:
model = Person
Specifying alternative data for a column
Each column has a “key” that describes which value to pull from each record to populate the column’s cells. By default, this key is just the name given to the column, but it can be changed to allow foreign key traversal or other complex cases.
To reduce ambiguity, rather than calling it a “key”, it’s been given the special name “accessor”.
Accessors are just dotted paths that describe how an object should be traversed to reach a specific value. To demonstrate how they work we’ll use them directly:
>>> from django_tables2 import A
>>> data = {"abc": {"one": {"two": "three"}}}
>>> A("abc.one.two").resolve(data)
"three"
Dots represent a relationships, and are attempted in this order:
- Dictionary lookup a[b]
- Attribute lookup a.b
- List index lookup a[int(b)]
Then, if the value is callable, it is called and the result is used.
Specifying alternative ordering for a column
When using queryset data, it’s possible for a column to present a computed value that doesn’t correspond to a column in the database. In this situation attempting to order the column will cause a database exception.
Example:
# models.py
class Person(models.Model):
first_name = models.CharField(max_length=200)
family_name = models.CharField(max_length=200)
@property
def name(self):
return u"%s %s" % (self.first_name, self.family_name)
# tables.py
class PersonTable(tables.Table):
name = tables.Column()
>>> table = PersonTable(Person.objects.all())
>>> table.order_by = "name"
>>> table.as_html()
...
FieldError: Cannot resolve keyword u'name' into field. Choices are: first_name, family_name
The solution is to declare which fields should be used when ordering on via the order_byargument:
# tables.py
class PersonTable(tables.Table):
name = tables.Column(order_by=("first_name", "family_name"))
Accessor syntax can be used for the values, but they must terminate on a model field.
If ordering doesn’t make sense for a particular column, it can be disabled via the orderableargument:
class SimpleTable(tables.Table):
name = tables.Column()
actions = tables.Column(orderable=False)
Swapping the position of columns
By default columns are positioned in the same order as they are declared, however when mixing auto-generated columns (via Table.Meta.model) with manually declared columns, the column sequence becomes ambiguous.
To resolve the ambiguity, columns sequence can be declared via the Table.Meta.sequence option:
class PersonTable(tables.Table):
selection = tables.CheckBoxColumn(accessor="pk", orderable=False)
class Meta:
model = Person
sequence = ("selection", "first_name", "last_name")
The special value "..." can be used to indicate that any omitted columns should inserted at that location. As such it can be used at most once.
Customising column headings
The header cell for each column comes from header. By default this method returnsverbose_name, falling back to the titlised attribute name of the column in the table class.
When using queryset data and a verbose name hasn’t been explicitly defined for a column, the corresponding model field’s verbose name will be used.
Consider the following:
>>> class Person(models.Model):
... first_name = models.CharField(verbose_name='model verbose name', max_length=200)
... last_name = models.CharField(max_length=200)
... region = models.ForeignKey('Region')
...
>>> class Region(models.Model):
... name = models.CharField(max_length=200)
...
>>> class PersonTable(tables.Table):
... first_name = tables.Column()
... ln = tables.Column(accessor='last_name')
... region_name = tables.Column(accessor='region.name')
...
>>> table = PersonTable(Person.objects.all())
>>> table.columns['first_name'].header
u'Model Verbose Name'
>>> table.columns['ln'].header
u'Last Name'
>>> table.columns['region_name'].header
u'Name'
As you can see in the last example (region name), the results are not always desirable when an accessor is used to cross relationships. To get around this be careful to defineColumn.verbose_name.
Pagination
Pagination is easy, just call Table.paginate() and pass in the current page number, e.g.
def people_listing(request):
table = PeopleTable(Person.objects.all())
table.paginate(page=request.GET.get('page', 1), per_page=25)
return render(request, 'people_listing.html', {'table': table})
If you’re using RequestConfig, pass pagination options to the constructor, e.g.:
def people_listing(request):
table = PeopleTable(Person.objects.all())
RequestConfig(request, paginate={"per_page": 25}).configure(table)
return render(request, 'people_listing.html', {'table': table})
Custom rendering
Various options are available for changing the way the table is rendered. Each approach has a different balance of ease-of-use and flexibility.
Table.render_FOO() methods
To change how a column is rendered, implement a render_FOO method on the table (where FOOis the column name). This approach is suitable if you have a one-off change that you don’t want to use in multiple tables.
Supported keyword arguments include:
- record – the entire record for the row from the table data
- value – the value for the cell retrieved from the table data
- column – the Column object
- bound_column – the BoundColumn object
- bound_row – the BoundRow object
- table – alias for self
Here’s an example where the first column displays the current row number:
>>> import django_tables2 as tables
>>> import itertools
>>> class SimpleTable(tables.Table):
... row_number = tables.Column(empty_values=())
... id = tables.Column()
... age = tables.Column()
...
... def __init__(self, *args, **kwargs):
... super(SimpleTable, self).__init__(*args, **kwargs)
... self.counter = itertools.count()
...
... def render_row_number(self):
... return 'Row %d' % next(self.counter)
...
... def render_id(self, value):
... return '<%s>' % value
...
>>> table = SimpleTable([{'age': 31, 'id': 10}, {'age': 34, 'id': 11}])
>>> for cell in table.rows[0]:
... print cell
...
Row 0
<10>
31
Python’s inspect.getargspec is used to only pass the arguments declared by the function. This means it’s not necessary to add a catch all (**) keyword argument.
Important
render methods are only called if the value for a cell is determined to be not an empty value. When a value is in Column.empty_values, a default value is rendered instead (both Column.renderand Table.render_FOO are skipped).
Subclassing Column
Defining a column subclass allows functionality to be reused across tables. Columns have arender method that behaves the same as Table.render_FOO() methods methods on tables:
>>> import django_tables2 as tables
>>>
>>> class UpperColumn(tables.Column):
... def render(self, value):
... return value.upper()
...
>>> class Example(tables.Table):
... normal = tables.Column()
... upper = UpperColumn()
...
>>> data = [{'normal': 'Hi there!',
... 'upper': 'Hi there!'}]
...
>>> table = Example(data)
>>> table.as_html()
u'<table><thead><tr><th>Normal</th><th>Upper</th></tr></thead><tbody><tr><td>Hi there!</td><td>HI THERE!</td></tr></tbody></table>\n'
See Table.render_FOO() methods for a list of arguments that can be accepted.
For complicated columns, you may want to return HTML from the render() method. This is fine, but be sure to mark the string as safe to avoid it being escaped:
>>> from django.utils.safestring import mark_safe
>>> from django.utils.html import escape
>>>
>>> class ImageColumn(tables.Column):
... def render(self, value):
... return mark_safe('<img src="/media/img/%s.jpg" />'
... % escape(value))
...
CSS
In order to use CSS to style a table, you’ll probably want to add a class or id attribute to the<table> element. django-tables2 has a hook that allows abitrary attributes to be added to the<table> tag.
>>> import django_tables2 as tables
>>> class SimpleTable(tables.Table):
... id = tables.Column()
... age = tables.Column()
...
... class Meta:
... attrs = {'class': 'mytable'}
...
>>> table = SimpleTable()
>>> table.as_html()
'<table class="mytable">...'
Custom Template
And of course if you want full control over the way the table is rendered, ignore the built-in generation tools, and instead pass an instance of your Table subclass into your own template, and render it yourself.
Have a look at the django_tables2/table.html template for an example.
Querystring fields
Tables pass data via the querystring to indicate ordering and pagination preferences.
The names of the querystring variables are configurable via the options:
- order_by_field – default: "sort"
- page_field – default: "page"
- per_page_field – default: "per_page", note: this field currently isn’t used by {% render_table %}
Each of these can be specified in three places:
- Table.Meta.foo
- Table(..., foo=...)
- Table(...).foo = ...
If you’re using multiple tables on a single page, you’ll want to prefix these fields with a table-specific name. e.g.
def people_listing(request):
config = RequestConfig(request)
table1 = PeopleTable(Person.objects.all(), prefix="1-") # prefix specified
table2 = PeopleTable(Person.objects.all(), prefix="2-") # prefix specified
config.configure(table1)
config.configure(table2)
return render(request, "people_listing.html",
{"table1": table1, "table2": table2})
Column attributes
Column attributes can be specified using the dict with specific keys. The dict defines HTML attributes for one of more elements within the column. Depending on the column, different elements are supported, however th, td, and cell are supported universally.
e.g.
>>> import django_tables2 as tables
>>>
>>> class SimpleTable(tables.Table):
... name = tables.Column(attrs={"th": {"id": "foo"}})
...
>>> SimpleTable(data).as_html()
"{snip}<thead><tr><th id="foo" class="name">{snip}<tbody><tr><td class="name">{snip}"
th and td are special cases because they’re extended during rendering to add the column name as a class. This is done to make writing CSS easier. Have a look at each column’s API reference to find which elements are supported.
Built-in columns
For common use-cases the following columns are included:
- BooleanColumn – renders boolean values
- Column – generic column
- CheckBoxColumn – renders checkbox form inputs
- DateColumn – date formatting
- DateTimeColumn – datetime formatting in the local timezone
- FileColumn – renders files as links
- EmailColumn – renders <a href="mailto:..."> tags
- LinkColumn – renders <a href="..."> tags (compose a django url)
- TemplateColumn – renders template code
- URLColumn – renders <a href="..."> tags (absolute url)
Template tags
render_table
Renders a Table object to HTML and enables as many features in the output as possible.
{% load django_tables2 %}
{% render_table table %}
{# Alternatively a specific template can be used #}
{% render_table table "path/to/custom_table_template.html" %}
If the second argument (template path) is given, the template will be rendered with aRequestContext and the table will be in the variable table.
Note
This tag temporarily modifies the Table object during rendering. A context attribute is added to the table, providing columns with access to the current context for their own rendering (e.g.TemplateColumn).
This tag requires that the template in which it’s rendered contains the HttpRequest inside arequest variable. This can be achieved by ensuring the TEMPLATE_CONTEXT_PROCESSORS setting contains "django.core.context_processors.request". By default it is not included, and the setting itself is not even defined within your project’s settings.py. To resolve this add the following to your settings.py:
from django.conf.global_settings import TEMPLATE_CONTEXT_PROCESSORS
TEMPLATE_CONTEXT_PROCESSORS += ('django.core.context_processors.request',)
querystring
A utility that allows you to update a portion of the query-string without overwriting the entire thing.
Let’s assume we have the querystring ?search=pirates&sort=name&page=5 and we want to update thesort parameter:
{% querystring "sort"="dob" %} # ?search=pirates&sort=dob&page=5
{% querystring "sort"="" %} # ?search=pirates&page=5
{% querystring "sort"="" "search"="" %} # ?page=5
{% with "search" as key %} # supports variables as keys
{% querystring key="robots" %} # ?search=robots&page=5
{% endwith %}
This tag requires the django.core.context_processors.request context processor, see render_table.
Template filters
title
String filter that performs title case conversion on a per-word basis, leaving words containing upper-case letters alone.
{{ "start 6PM"|title }} # Start 6PM
{{ "sTart 6pm"|title }} # sTart 6pm
Warning
Be careful when loading the django_tables2 template library to not in advertantly load title. You should always use the {% load ... from ... %} syntax.
Class Based Generic Mixins
Django 1.3 introduced class based views as a mechanism to reduce the repetition in view code. django-tables2 comes with a single class based view mixin: SingleTableMixin. It makes it trivial to incorporate a table into a view/template.
The following view parameters are supported:
- table_class –- the table class to use, e.g. SimpleTable
- table_data (or get_table_data()) – the data used to populate the table
- context_table_name – the name of template variable containing the table object
- table_pagination – pagination options to pass to RequestConfig
For example:
from django_tables2 import SingleTableView
class Person(models.Model):
first_name = models.CharField(max_length=200)
last_name = models.CharField(max_length=200)
class PersonTable(tables.Table):
class Meta:
model = Simple
class PersonList(SingleTableView):
model = Person
table_class = PersonTable
The template could then be as simple as:
{% load render_table from django_tables2 %}
{% render_table table %}
Such little code is possible due to the example above taking advantage of default values andSimpleTableMixin‘s eagarness at finding data sources when one isn’t explicitly defined.
Note
If you need more than one table on a page, use SingleTableView and use get_context_data to initialise the other tables and add them to the context.
Note
You don’t have to base your view on ListView, you’re able to mix SingleTableMixin directly.
Table Mixins
It’s possible to create a mixin for a table that overrides something, however unless it itself is a subclass of Table class variable instances of Column will not be added to the class which is using the mixin.
Example:
>>> class UselessMixin(object):
... extra = tables.Column()
...
>>> class TestTable(UselessMixin, tables.Table):
... name = tables.Column()
...
>>> TestTable.base_columns.keys()
['name']
To have a mixin contribute a column, it needs to be a subclass of Table. With this in mind the previous example should have been written as follows:
>>> class UsefulMixin(tables.Table):
... extra = tables.Column()
...
>>> class TestTable(UsefulMixin, tables.Table):
... name = tables.Column()
...
>>> TestTable.base_columns.keys()
['extra', 'name']
Tables for models
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
class Person(models.Model):
first_name = models.CharField(max_length=200)
last_name = models.CharField(max_length=200)
user = models.ForeignKey("auth.User")
dob = models.DateField()
# tables.py
class PersonTable(tables.Table):
class Meta:
model = Person
This has a number of benefits:
- Less code, easier to write, more DRY
- Columns use the field’s verbose_name
- Specialised columns are used where possible (e.g. DateColumn for a DateField)
When using this approach, the following options are useful:
Controlling localization
Note
This functionality doesn’t work in Django prior to version 1.3
Django_tables2 allows you to define which column of a table should or should not be localized. For example you may want to use this feature in following use cases:
- You want to format some columns representing for example numeric values in the given locales even if you don’t enable USE_L10N in your settings file.
- You don’t want to format primary key values in your table even if you enabled USE_L10N in your settings file.
This control is done by using two filter functions in Django’s l10n library named localize andunlocalize. Check out Django docs about localization for more information about them.
There are two ways of controling localization in your columns.
First one is setting the localize attribute in your column definition to True or False. Like so:
class PersonTable(tables.Table):
id = tables.Column(name="id", accessor="pk", localize=False)
class Meta:
model = Person
Note
The default value of the localize attribute is None which means the formatting of columns is dependant from the USE_L10N setting.
The second way is to define a localize and/or unlocalize tuples in your tables Meta class (jutst like with fields or exclude). You can do this like so:
class PersonTable(tables.Table):
id = tables.Column(accessor="pk")
value = tables.Column(accessor="some_numerical_field")
class Meta:
model = Person
unlocalize = ('id',)
localize = ('value',)
If you define the same column in both localize and unlocalize then the value of this column will be “unlocalized” which means that unlocalize has higher precedence.
API Reference
Accessor (A)
-
class
django_tables2.utils.
Accessor
[source]
-
A string describing a path from one object to another via attribute/index accesses. For convenience, the class has an alias A to allow for more concise code.
Relations are separated by a . character.
RequestConfig
-
class
django_tables2.config.
RequestConfig
(
request,
paginate=True
)
[source]
-
A configurator that uses request data to setup a table.
Parameters: paginate (dict or bool) – indicates whether to paginate, and if so, what default values to use. If the value evaluates to False, pagination will be disabled. A dict can be used to specify default values for the call to paginate (e.g. to define a defaultper_page value).
A special silent item can be used to enable automatic handling of pagination exceptions using the following algorithm:
- If PageNotAnInteger` is raised, show the first page.
- If EmptyPage is raised, show the last page.
Table
-
class
django_tables2.tables.
Table
(
data,
order_by=None,
orderable=None,
empty_text=None,
exclude=None,
attrs=None,
sequence=None,
prefix=None,
order_by_field=None,
page_field=None,
per_page_field=None,
template=None,
sortable=None,
default=None,
request=None
)
-
-
as_html
(
)
-
Render the table to a simple HTML table.
If this method is used in the request/response cycle, any links generated will clobber the querystring of the request. Use the {% render_table %} template tag instead.
-
paginate
(
klass=<class 'django.core.paginator.Paginator'>,
per_page=None,
page=1,
*args,
**kwargs
)
-
Paginates the table using a paginator and creates a page property containing information for the current page.
Parameters: Extra arguments are passed to the paginator.
Pagination exceptions (EmptyPage and PageNotAnInteger) may be raised from this method and should be handled by the caller.
-
Table.Meta
-
class
Table.
Meta
-
Provides a way to define global settings for table, as opposed to defining them for each instance.
-
attrs
-
Allows custom HTML attributes to be specified which will be added to the <table> tag of any table rendered via Table.as_html() or the render_table template tag.
Type: dict Default: {} This is typically used to enable a theme for a table (which is done by adding a CSS class to the <table> element). i.e.:
class SimpleTable(tables.Table): name = tables.Column() class Meta: attrs = {"class": "paleblue"}
New in version 0.15.0.
It’s possible to use callables to create dynamic values. A few caveats:
- It’s not supported for dict keys, i.e. only values.
- All values will be resolved on table instantiation.
Consider this example where a unique id is given to each instance of the table:
import itertools counter = itertools.count() class UniqueIdTable(tables.Table): name = tables.Column() class Meta: attrs = {"id": lambda: "table_%d" % next(counter)}
Note
This functionality is also available via the attrs keyword argument to a table’s constructor.
-
empty_text
-
Defines the text to display when the table has no rows.
Type: unicode Default: None If the table is empty and bool(empty_text) is True, a row is displayed containingempty_text. This is allows a message such as There are currently no FOO. to be displayed.
Note
This functionality is also available via the empty_text keyword argument to a table’s constructor.
-
exclude
-
Defines which columns should be excluded from the table. This is useful in subclasses to exclude columns in a parent.
Type: tuple of unicode Default: () Example:
>>> class Person(tables.Table): ... first_name = tables.Column() ... last_name = tables.Column() ... >>> Person.base_columns {'first_name': <django_tables2.columns.Column object at 0x10046df10>, 'last_name': <django_tables2.columns.Column object at 0x10046d8d0>} >>> class ForgetfulPerson(Person): ... class Meta: ... exclude = ("last_name", ) ... >>> ForgetfulPerson.base_columns {'first_name': <django_tables2.columns.Column object at 0x10046df10>}
Note
This functionality is also available via the exclude keyword argument to a table’s constructor.
However, unlike some of the other Table.Meta options, providing the exclude keyword to a table’s constructor won’t override the Meta.exclude. Instead, it will be effectively be added to it. i.e. you can’t use the constructor’s exclude argument to undo an exclusion.
-
fields
-
Used in conjunction with model, specifies which fields should have columns in the table.
Type: tuple of unicode or None Default: None If None, all fields are used, otherwise only those named.
Example:
# models.py class Person(models.Model): first_name = models.CharField(max_length=200) last_name = models.CharField(max_length=200) # tables.py class PersonTable(tables.Table): class Meta: model = Person fields = ("first_name", )
-
model
-
A model to inspect and automatically create corresponding columns.
Type: Django model Default: None This option allows a Django model to be specified to cause the table to automatically generate columns that correspond to the fields in a model.
-
order_by
-
The default ordering. e.g. ('name', '-age'). A hyphen - can be used to prefix a column name to indicate descending order.
Type: tuple Default: () Note
This functionality is also available via the order_by keyword argument to a table’s constructor.
-
sequence
-
The sequence of the table columns. This allows the default order of columns (the order they were defined in the Table) to be overridden.
Type: any iterable (e.g. tuple or list) Default: () The special item "..." can be used as a placeholder that will be replaced with all the columns that weren’t explicitly listed. This allows you to add columns to the front or back when using inheritence.
Example:
>>> class Person(tables.Table): ... first_name = tables.Column() ... last_name = tables.Column() ... ... class Meta: ... sequence = ("last_name", "...") ... >>> Person.base_columns.keys() ['last_name', 'first_name']
The "..." item can be used at most once in the sequence value. If it’s not used, every column must be explicitly included. e.g. in the above example, sequence = ("last_name", )would be invalid because neither "..." or "first_name" were included.
Note
This functionality is also available via the sequence keyword argument to a table’s constructor.
-
orderable
-
Default value for column’s orderable attribute.
Type: bool Default: True If the table and column don’t specify a value, a column’s orderable value will fallback to this. object specify. This provides an easy mechanism to disable ordering on an entire table, without adding orderable=False to each column in a table.
Note
This functionality is also available via the orderable keyword argument to a table’s constructor.
-
template
-
The default template to use when rendering the table.
Type: unicode Default: "django_tables2/table.html" Note
This functionality is also available via the template keyword argument to a table’s constructor.
-
localize
-
Specifies which fields should be localized in the table. Read Controlling localization for more information.
Type: tuple of unicode Default: empty tuple
-
unlocalize
-
Specifies which fields should be unlocalized in the table. Read Controlling localization for more information.
Type: tuple of unicode Default: empty tuple
-
BooleanColumn
-
class
django_tables2.columns.
BooleanColumn
(
null=False,
yesno=u'u2714,
u2718',
**kwargs
)
-
A column suitable for rendering boolean data.
Parameters: Rendered values are wrapped in a <span> to allow customisation by themes. By default the span is given the class true, false.
In addition to attrs keys supported by Column, the following are available:
- span – adds attributes to the <span> tag
Column
-
class
django_tables2.columns.
Column
(
verbose_name=None,
accessor=None,
default=None,
visible=True,
orderable=None,
attrs=None,
order_by=None,
sortable=None,
empty_values=None,
localize=None
)
-
Represents a single column of a table.
Column objects control the way a column (including the cells that fall within it) are rendered.
-
attrs
-
HTML attributes for elements that make up the column.
Type: dict This API is extended by subclasses to allow arbitrary HTML attributes to be added to the output.
By default Column supports:
- th – table/thead/th elements
- td – table/tbody/tr/td elements
- cell – fallback if th or td isn’t defined
-
accessor
-
An accessor that describes how to extract values for this column from the table data.
Type: string or Accessor
-
default
-
The default value for the column. This can be a value or a callable object [1]. If an object in the data provides None for a column, the default will be used instead.
The default value may affect ordering, depending on the type of data the table is using. The only case where ordering is not affected is when a QuerySet is used as the table data (since sorting is performed by the database).
[1] The provided callable object must not expect to receive any arguments.
-
order_by
-
Allows one or more accessors to be used for ordering rather than accessor.
Type: unicode, tuple, Accessor
-
verbose_name
-
A human readable version of the column name.
Type: unicode
-
localize
-
This attribute doesn’t work in Django 1.2
- If True, cells of this column will be localized in the HTML output by the localize filter.
- If False, cells of this column will be unlocalized in the HTML output by the unlocalize filter.
- If None (the default), cell will be rendered as is and localization will depend on USE_L10Nsetting.
Type: bool
-
CheckBoxColumn
-
class
django_tables2.columns.
CheckBoxColumn
(
attrs=None,
**extra
)
-
A subclass of Column that renders as a checkbox form input.
This column allows a user to select a set of rows. The selection information can then be used to apply some operation (e.g. “delete”) onto the set of objects that correspond to the selected rows.
The value that is extracted from the table data for this column is used as the value for the checkbox, i.e. <input type="checkbox" value="..." />
This class implements some sensible defaults:
- HTML input’s name attribute is the column name (can override via attrs argument).
- orderable defaults to False.
Note
You’d expect that you could select multiple checkboxes in the rendered table and then do something with that. This functionality isn’t implemented. If you want something to actually happen, you’ll need to implement that yourself.
In addition to attrs keys supported by Column, the following are available:
- input – <input> elements in both <td> and <th>.
- th__input – Replaces input attrs in header cells.
- td__input – Replaces input attrs in body cells.
DateColumn
-
class
django_tables2.columns.
DateColumn
(
format=None,
short=True,
*args,
**kwargs
)
-
A column that renders dates in the local timezone.
Parameters: - format (unicode) – format string in same format as Django’s date template filter (optional)
- short (bool) – if format is not specified, use Django’s SHORT_DATE_FORMATsetting, otherwise use DATE_FORMAT
DateTimeColumn
-
class
django_tables2.columns.
DateTimeColumn
(
format=None,
short=True,
*args,
**kwargs
)
-
A column that renders datetimes in the local timezone.
Parameters: - format (unicode) – format string for datetime (optional)
- short (bool) – if format is not specifid, use Django’s SHORT_DATETIME_FORMAT, else DATETIME_FORMAT
EmailColumn
-
class
django_tables2.columns.
EmailColumn
(
attrs=None,
*args,
**kwargs
)
-
A subclass of BaseLinkColumn that renders the cell value as a hyperlink.
It’s common to have a email value in a row hyperlinked to other page.
Parameters: attrs – a dict of HTML attributes that are added to the rendered<a href="...">...</a> tag Example:
# models.py class Person(models.Model): name = models.CharField(max_length=200) email = models.EmailField() # tables.py class PeopleTable(tables.Table): name = tables.Column() email = tables.EmailColumn()
FileColumn
-
class
django_tables2.columns.
FileColumn
(
verify_exists=True,
**kwargs
)
-
Attempts to render FieldFile (or other storage backend File) as a hyperlink.
When the file is accessible via a URL, the file is rendered as a hyperlink. The basename is used as the text:
<a href="/media/path/to/receipt.pdf" title="path/to/receipt.pdf">receipt.pdf</a>
When unable to determine the URL, a span is used instead:
<span title="path/to/receipt.pdf">receipt.pdf</span>
Column.attrs keys a and span can be used to add additional attributes.
Parameters: verify_exists (bool) – attempt to determine if the file exists If verify_exists, the HTML class exists or missing is added to the element to indicate the integrity of the storage.
LinkColumn
-
class
django_tables2.columns.
LinkColumn
(
viewname,
urlconf=None,
args=None,
kwargs=None,
current_app=None,
attrs=None,
**extra
)
-
Renders a normal value as an internal hyperlink to another page.
It’s common to have the primary value in a row hyperlinked to the page dedicated to that record.
The first arguments are identical to that of reverse and allows an internal URL to be described. The last argument attrs allows custom HTML attributes to be added to the rendered <a href="..."> tag.
Parameters: ** In order to create a link to a URL that relies on information in the current row, Accessorobjects can be used in the args or kwargs arguments. The accessor will be resolved using the row’s record before reverse is called.
Example:
# models.py class Person(models.Model): name = models.CharField(max_length=200) # urls.py urlpatterns = patterns('', url('people/(\d+)/', views.people_detail, name='people_detail') ) # tables.py from django_tables2.utils import A # alias for Accessor class PeopleTable(tables.Table): name = tables.LinkColumn('people_detail', args=[A('pk')])
In addition to attrs keys supported by Column, the following are available:
- a – <a> elements in <td>.
TemplateColumn
-
class
django_tables2.columns.
TemplateColumn
(
template_code=None,
template_name=None,
**extra
)
-
A subclass of Column that renders some template code to use as the cell value.
Parameters: - template_code (unicode) – the template code to render
- template_name (unicode) – the name of the template to render
A Template object is created from the template_code or template_name and rendered with a context containing:
- record – data record for the current row
- value – value from record that corresponds to the current column
- default – appropriate default value to use as fallback
Example:
class ExampleTable(tables.Table): foo = tables.TemplateColumn('{{ record.bar }}') # contents of `myapp/bar_column.html` is `{{ value }}` bar = tables.TemplateColumn(template_name='myapp/name2_column.html')
Both columns will have the same output.
Important
In order to use template tags or filters that require a RequestContext, the table must be rendered via {% render_table %}.
URLColumn
-
class
django_tables2.columns.
URLColumn
(
attrs=None,
*args,
**kwargs
)
-
Renders URL values as hyperlinks.
Example:
>>> class CompaniesTable(tables.Table): ... www = tables.URLColumn() ... >>> table = CompaniesTable([{"www": "http://google.com"}]) >>> table.rows[0]["www"] u'<a href="http://google.com">http://google.com</a>'
Additional attributes for the <a> tag can be specified via attrs['a'].
See Internal APIs for internal classes.
Upgrading from django-tables Version 1
-
Change your INSTALLLED_APPS entry from "django_tables.app" to "django_tables2".
-
Change all your import references from django_tables to django_tables2.
-
Replace all references to the old MemoryTable and ModelTable classes with simply Table.
-
In your templates, load the django_tables2 template library; {% load django_tables2 %} instead of {% load tables %}.
-
A table object is no longer iterable; rather than for row in table, instead you now do explicitly: for row in table.rows.
-
If you were using row.data to access a row’s underlying data, replace it with row.recordinstead.
-
When declaring columns, replace the use of:
name_in_dataset = tables.Column(name="wanted_column_name")
with:
wanted_column_name = tables.Column(accessor="name_in_dataset")
-
When declaring columns, replace the use of:
column_to_override = tables.Column(name="wanted_column_name", data="name_in_dataset")
with:
wanted_column_name = tables.Column(accessor="name_in_dataset")
and exclude column_to_override via the table meta data.
-
When generating the link to order the column, instead of:
{% set_url_param sort=column.name_toggled %}
use:
{% querystring table.order_by_field=column.order_by_alias.next %}
-
Replace:
{{ column.is_ordered_reverse }} and {{ column.is_ordered_straight }}
with:
{{ column.order_by.is_descending }} and {{ column.order_by.is_ascending }}
Glossary
-
accessor
- Refers to an Accessor object column name
-
The name given to a column. In the follow example, the column name is age.
class SimpleTable(tables.Table): age = tables.Column()
empty value
- An empty value is synonymous with “no value”. Columns have an empty_values attribute that contains values that are considered empty. It’s a way to declare which values from the database correspond to null/ blank/ missing etc. order by alias
-
A prefixed column name that describes how a column should impact the order of data within the table. This allows the implementation of how a column affects ordering to be abstracted, which is useful (e.g. in querystrings).
class ExampleTable(tables.Table): name = tables.Column(order_by=('first_name', 'last_name'))
In this example -name and name are valid order by aliases. In a querystring you might then have ?order=-name.
table
- The traditional concept of a table. i.e. a grid of rows and columns containing data. view
- A Django view. record
- A single Python object used as the data for a single row. render
- The act of serialising a Table into HTML. template
- A Django template. table data
- An interable of records that Table uses to populate its rows.
© Copyright .