NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
PyPI · #4384 most downloaded on PyPI
Table/data-grid framework for Django
Last release 1 months ago
30 Aug 2026
Release timing varies
gaps range from 2 weeks to 1.2 years
Nearly every release is documented
notes for 59 of the last 60 stable releases
1 version withdrawn
withdrawn after publishing
15 years old
135 releases · first in 2011
- Add support for Django 6.1 - Remove support for Python 3.10
Rename the querystring templatetag to querystring_replace to avoid shadowing built-in one. If you use custom templates to render tables with django-ta
Breaking changes:
querystring templatetag to querystring_replace to avoid shadowing built-in one.
If you use custom templates to render tables with django-tables2, you should replace
{% querystring %} with {% querystring_replace %}RelatedLinkColumn is removed. Replace RelatedLinkColumn with Column(linkify=True).Changes:
One column per quarter.
This release is yanked because it should have been released as 3.0 because of the breaking changes.
This release is yanked because it should have been released as 3.0 because of the breaking changes.
Changes:
RelatedLinkColumn and NullBooleanField support (#1016)
NullBooleanField was removed in django 4.0DateColumn/DateTimeColumn/TimeColumn in ISO format (#1022 by @spapas)querystring template tag to querystring_replace (#1021 by @federicobond)inspect.signature to prevent runtime errors with type annotations (#1027) by @mschoettlecontext_object_name to TemplateColumn and make extra_context optionally callable (#931) fixes: #928Pass request to the template rendered in TemplateColumn (#1014) Fixes: #1008
request to the template rendered in TemplateColumn (#1014) Fixes: #1008Update django.po for Ukrainian 🇺🇦 (#934) by @DmytroLitvinov
Remove upper bound for python_requires
Correct packaging mistakes:
python_requiresNothing published for this version
Add python_requires to setup.py (#982) Fixes: #980
Add TimeColumn to built-in columns (#937) by @philipphanemann Add support to pass args/kwargs to callables from Accessor (#940), fixes: #939 by @Jorda
Column.accessor when binding a column to allow column methods like order_by to use its value (#979)Update docs dependencies; fix docs search; add readthedocs.yaml
Accessor to documentation in custom-data.rst (#917) by @ruddra{% load l10n %} in templates (#919) by @tvanekerisFix bootstrap5-responsive template to extend bootstrap5 (#909) by @mschoettle
Assign request to table before anything else in RequestConfig.configure() (#888) fixes: #865
RequestConfig.configure() (#888) fixes: #865Assign request to table before anything else in RequestConfig.configure() (#888) fixes: #865
TableMixinBase: implement get_paginate_by (#811) by @Alirezaja1384
TableMixinBase: implement get_paginate_by (#811) by @Alirezaja1384Dropped support for python 3.6, added support for python 3.11
LinkColumn's attrs callables too (#852) by @wsldankersbootstrap5.html to support bootstrap 5 (#880, fixes #796Add Persian (Farsi) locale (#806) by @Alirezaja1384
Add support for django 3.2 and python 3.9, drop support for django 3.0
Removed deprecation warnings with django==3.1 regarding JSONField #785
JSONField #785Use table.default for empty ManyToMany relations (#773) fixes: #769
Fix popping the extra_context of TemplateColumn #767 by @bernhardmiller
format_html import to prevent NameError #752 by @MBfromOKFixed the LazyPaginator in a simpler more predictable way: an attempt to show a non-existent page, shows the first page. #743
LazyPaginator in a simpler more predictable way: an attempt to show a non-existent page, shows the first page. #743Add ability to pass tablib.Dataset kwargs via TableExport and ExportMixin #720 by @powderflask
tablib.Dataset kwargs via TableExport and ExportMixin #720 by @powderflaskAccessor.resolve() if the context contains the exact accessor #722, fixes #717metaclass keyword argument, as all supported python versions support it. #742LazyPaginator with non-existent page number should not result in a crash #741Fix backwards-compatibility with legacy separators in order_by clauses (#715 by @federicobond)
Use __ as accessor-separator, add linkify Meta option #702). This will currently emit a warning but falls back to using . as separator. The next major
__ as accessor-separator, add linkify Meta option #702).
This will currently emit a warning but falls back to using . as separator. The next major version will raise a ValueError if used with . as separator.LazyPaginator if not on last page (#707 by @tuky)Made ManyToManyColumn use table.default instead of a local value #680 by @srtab
Dropped support for python 2.7 (and django 1.11).
django_tables2.utils.ucfirst, use django.utils.text.capfirst instead.class="thead-default" from bootstrap4 template (#671)visible=False in export (#677)Add optional 'table' kwarg to row_attrs callables
row_attrs callablesFixes issue with wrong time format for TimeColumn #650 by @IgorCode
The ValueError raised if the QuerySet passed to a table instance did not match the value declared in Meta.model is now turned into a warning (fixes #6
ValueError raised if the QuerySet passed to a table instance did not match the value declared in Meta.model is now turned into a warning (fixes #643)thead/tfoot attributes are not defined #624 by @intioceanImprovements in packaging and publishing helper scripts reducing the package size considerably #630 by @wtayyeb (fixes #629)
Make sure the value of the class attribute in has consistent ordering (fixes #627)
<th> has consistent ordering (fixes #627)Fixed a regression which did not allow Table.Meta.order_by to be a list.
Table.Meta.order_by to be a list.Not much changed in this final version, but quite a lot if you are still on 1.21.2. Some breaking changes were introduced in version 2.0.0a0, so befor…
Not much changed in this final version, but quite a lot if you are still on 1.21.2. Some breaking changes were introduced in version 2.0.0a0, so before upgrading from 1.21.2, please have a look through them carefully.
Change order of logic in get_table_pagination to make sure we are able to override the paginator using View.paginator_class attribute.
get_table_pagination to make sure we are able to override the paginator using View.paginator_class attribute.The klass argument to Table.paginate() is renamed to paginator_class
klass argument to Table.paginate() is renamed to paginator_classListView attributes paginator_class and paginate_orphans into account.Fixed a bug in the implementation of #606
Added the ability to change the html attributes for thead, tbody, tfoot tags #606 by @roelbouwman
thead, tbody, tfoot tags #606 by @roelbouwmanAdded LazyPaginator to prevent making .count() queries (#604).
LazyPaginator to prevent making .count() queries (#604).Added linkify_item keyword argument to ManyToManyColumn, fixes #594
linkify_item keyword argument to ManyToManyColumn, fixes #594README.md preventing installation in some environments.Add linkify keyword argument to all columns, to allow wrapping the content in a tag. It accepts one of these ways to define the link:
linkify keyword argument to all columns, to allow wrapping the content in a <a> tag.
It accepts one of these ways to define the link:
True to use the record return value of record.get_absolute_url(),django.urls.reverse()django.urls.reverse().
Implementation should be backwards compatible, so all use of LinkColumn and RelatedLinkColum should still work. #590Fix table prefix being overwritten in MultiTableView, #576 by @ETinLV, (fixes #572)
Hello from DjangoCon Europe!
Another round of template cleanup.
RelatedLinkColumn for records without get_absolute_url().ValueError when Table.Meta.model != QuerySet.Model.TypeError when incorrect types are used for Table.Meta attributes (fixes #517)Table.Meta.sequence with extra_columns can leads to KeyError (fixes #486)Fixed translation of 'previous' for some languages (fixes #563)
Cleaned up templates to add consistency in what is presented across all templates.
template argument to the table constructor, use template_name instead.<td> tags) by default.
Previous behavior can be restored by using this method on your custom table:class MyTable(tables.Table):
# columns
def get_column_class_names(self, classes_set, bound_column):
classes_set = super(MyTable, self).get_column_class_names(classes_set, bound_column)
classes_set.add(bound_column.name)
return classes_set
verbose_names derived from model fields are not passed through title() anymore, only the first character is converted to upper case. This follows Django's convention for verbose field names: "The convention is not to capitalize the first letter of the verbose_name. Django will automatically capitalize the first letter where it needs to." (Fixes #475 and #491)Moved table instantiation from get_context_data to get_tables #554 by @sdolemelipone
get_context_data to get_tables #554 by @sdolemeliponetemplate.render(), rather than as part of context. (fixes #552)Do not perform extra COUNT() queries for non-paginated tables. Fixes #551
COUNT() queries for non-paginated tables. Fixes #551Prevent mutation of the template context {% render_table %} is called from (fixes #547) Possible breaking change: the context variables of the templat…
paginated_rows to Table to replace fallback to non-paginated rows in templates.{% render_table %} is called from (fixes #547)
Possible breaking change: the context variables of the template {% render_table %} is called from is no longer available in the table's template. The table variable has an attribute context, which is the context of the calling template. Use {{ table.context.variable }} instead of {{ variable }}.Define and use get_table_data in MultiTableMixin #538 by @vCra (fixes #528)
BoundColumn.attrs does not evaluate current_value as bool #536 by @pachewise (fixes #534)
BoundColumn.attrs does not evaluate current_value as bool #536 by @pachewise (fixes #534)Renamed Table.Meta.template to template_name (with deprecation warning for the former) #542 (fixes #520)
Fix typo in setup.py for extras_require.
extras_require.Dropped support for Django 1.8, 1.9 and 1.10.
extra_context argument to TemplateColumn #509 by @ad-mstr #514, fixes #511django.test.TestCase for all tests, and remove dependency on pytest and reorganized some tests #515This is the last version supporting Django 1.8, 1.9 and 1.10. Django 1.8 is only supported until April 2018, so consider upgrading to Django 1.11!
This is the last version supporting Django 1.8, 1.9 and 1.10. Django 1.8 is only supported until April 2018, so consider upgrading to Django 1.11!
tf dictionary to Column.attrs with default values for the footer, so footers now have class attribute by default #501 by @mpasternakAdded as=varname keyword argument to the {% querystring %} template tag, fixes #481
as=varname keyword argument to the {% querystring %} template tag,
fixes #481OrderedDict rather than dict as the parent for utils.AttributeDict to make the rendered html more consistent across python versions.attrs from a column's attribute, allowing easier reuse of custom column attributes (fixes #241)value and record are optionally passed to the column attrs callables for data rows. #503, fixes #500Added a row_counter variable to the template context in TemplateColumn (fixes #448)
row_counter variable to the template context in TemplateColumn (fixes #448)Do not fail if orderable=False is passed to ManyToManyColumn()
orderable=False is passed to ManyToManyColumn()Added separator argument to ManyToManyColumn.
separator argument to ManyToManyColumn.mark_safe()'d strings from ManyToManyColumn.tranform()ManyToManyColumns by default.Made positional data argument to the table __init__() a keyword argument to make inheritance easier. Will raise a TypeError if omitted.
data argument to the table __init__() a keyword argument to make inheritance easier. Will raise a TypeError if omitted.Allow export file name customization #484 by @federicobond
Added Hungarian translation #471 by @hmikihth.
Your coding agent can read these notes before it upgrades. Set up the MCP server →