Change log

2.6.0 (2023-06-27)

  • Fix bootstrap5-responsive template to extend bootstrap5 (#909) by @mschoettle

  • Add support for django 4.2

  • Drop python 3.7 and django 4.0 support (#920)

2.5.3 (2023-03-05)

2.5.2 (2023-02-07)

  • Assign request to table before anything else in RequestConfig.configure() (#888) fixes: #865

2.5.1 (2023-01-07)

2.5.0 (2022-12-27)

  • Dropped support for python 3.6, added support for python 3.11

  • Add django_tables2/bootstrap4-responsive.html (#874) by @botlabsDev

  • Pass record/value to LinkColumn’s attrs callables too (#852) by @wsldankers

  • Add template bootstrap5.html to support bootstrap 5 (#880, fixes #796

2.4.1 (2021-10-04)

  • Add Persian (Farsi) locale (#806) by @Alirezaja1384

  • Improved error message if openpyxl is not installed (#816)

  • Use correct mime type for xlsx (fixes: #810)

  • Add support for django 4.0, drop support for python 3.5 (#822)

2.4.0 (2021-05-15)

  • Add support for django 3.2 and python 3.9, drop support for django 3.0

  • Add Django 3.0 and 3.1 trove classifiers #803 by @Asday

  • Strip leading and trailing whitespace from TemplateColumn.value() #794 by @jeremystretch

  • Providing link for django-bootstrap3 #793 by @TareqMonwer

  • Fix for crash on windows while deleting temp file #788

2.3.4 (2021-01-10)

  • Removed deprecation warnings with django==3.1 regarding JSONField #785

2.3.3 (2020-10-29)

  • Use table.default for empty ManyToMany relations (#773) fixes: #769

  • Pass record/value to CheckboxColumn’s attrs callables too (#774), fixes: #762

2.3.2 (2020-10-10)

  • Fix popping the extra_context of TemplateColumn #767 by @bernhardmiller

  • Fix typo for the translation of the word ‘next’ in greek [#759]]( by @orfeasa

  • Add format_html import to prevent NameError #752 by @MBfromOK

  • Fixed Russian translation #768 by @Real-Gecko

2.3.1 (2020-04-02)

  • Fixed the LazyPaginator in a simpler more predictable way: an attempt to show a non-existent page, shows the first page. #743

2.3.0 (2020-03-31)

  • Add ability to pass tablib.Dataset kwargs via TableExport and ExportMixin #720 by @powderflask

  • Drop django==2.1 support, add optional tablib requirements #738

  • Short-circuit Accessor.resolve() if the context contains the exact accessor #722, fixes #717

  • Fixed yaml export #732 by @sg3-141-592

  • Made Table docstring visible in docs #742

  • Removed the TableBase construct in favor of using the metaclass keyword argument, as all supported python versions support it. #742

  • LazyPaginator with non-existent page number should not result in a crash #741

2.2.1 (2019-11-20)

  • Fix backwards-compatibility with legacy separators in order_by clauses (#715 by @federicobond)

2.2.0 (2019-11-18)

  • 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 version will raise a ValueError if used with . as separator.

  • Add request attribute to table instance (#705 by @rubickcz).

  • Append ellipsis for LazyPaginator if not on last page (#707 by @tuky)

2.1.1 (2019-09-23)

  • Made ManyToManyColumn use table.default instead of a local value #680 by @srtab

  • Removed invalid scope attribute in <tr> element of bootstrap4.html. #691 by @vlt

  • Fixed an issue with incorrectly disabled pagination where SingleTableMixin was not used together with ListView #678 by @nieuwenhuys

2.1.0 (2019-07-22)

  • Dropped support for python 2.7 (and django 1.11).

  • Removed django_tables2.utils.ucfirst, use django.utils.text.capfirst instead.

  • Removed class="thead-default" from bootstrap4 template (#671)

  • Included columns with visible=False in export (#677)

  • Fixed pagination when the number of pages is equal to page range plus one (#655)

2.0.6 (2019-03-26)

  • Add optional ‘table’ kwarg to row_attrs callables

2.0.5 (2019-02-21)

  • Fixes issue with wrong time format for TimeColumn #650 by @IgorCode

2.0.4 (2019-01-21)

  • 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 #643)

  • Make sure the templates do not raise errors when thead/tfoot attributes are not defined #624 by @intiocean

2.0.3 (2018-11-11)

  • Improvements in packaging and publishing helper scripts reducing the package size considerably #630 by @wtayyeb (fixes #629)

  • Documentation improvements fixing #625, #631

2.0.2 (2018-10-22)

  • Make sure the value of the class attribute in <th> has consistent ordering (fixes #627)

  • Make sure that pagination block is available in template regardless of pagination status #622 by @apocalyptech

2.0.1 (2018-09-13)

  • Fixed a regression which did not allow Table.Meta.order_by to be a list.

2.0.0 (2018-09-13)

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.

  • Consider ExportMixin.export_trigger_param in export_url template tag #609 by @soerenbe

2.0.0b5 (2018-08-29)

  • Change order of logic in get_table_pagination to make sure we are able to override the paginator using View.paginator_class attribute.

2.0.0b4 (2018-08-29)

  • The klass argument to Table.paginate() is renamed to paginator_class

  • Table views/mixins now take ListView attributes paginator_class and paginate_orphans into account.

2.0.0b3 (2018-08-27)

  • Fixed a bug in the implementation of #606

2.0.0b2 (2018-08-27)

  • Added the ability to change the html attributes for thead, tbody, tfoot tags #606 by @roelbouwman

2.0.0b1 (2018-08-24)

  • Added LazyPaginator to prevent making .count() queries (#604).

2.0.0a5 (2018-07-28)

  • Added linkify_item keyword argument to ManyToManyColumn, fixes #594

  • Fixed an encoding issue in preventing installation in some environments.

2.0.0a4 (2018-07-17)

  • Add 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(),

    • a callable to use its return value

    • a dict which is passed on to django.urls.reverse()

    • a (viewname, args) or (viewname, kwargs)-tuple which is also passed on to django.urls.reverse(). Implementation should be backwards compatible, so all use of LinkColumn and RelatedLinkColum should still work. #590

2.0.0a3 (2018-05-24)

Hello from DjangoCon Europe!

  • Fix table prefix being overwritten in MultiTableView, #576 by @ETinLV, (fixes #572)

  • Fix empty_text cannot be translated (fixes #579)

2.0.0a2 (2018-04-13)

  • Another round of template cleanup.

  • Fresh screenshots

  • Prevent crash in RelatedLinkColumn for records without get_absolute_url().

  • Raise ValueError when Table.Meta.model != QuerySet.Model.

  • Raise TypeError when incorrect types are used for Table.Meta attributes (fixes #517)

  • Fix: Table.Meta.sequence with extra_columns can leads to KeyError (fixes #486)

2.0.0a1 (2018-04-12)

  • Fixed translation of ‘previous’ for some languages (fixes #563)

django-tables2 2.0.0a0 (2018-04-10)

  • Cleaned up templates to add consistency in what is presented across all templates.

  • Added bootstrap4.html template

  • Fixed translation inconsistencies.

breaking changes 2.0.0

  • Appearance of the paginators might be different from the current 1.x templates. Use a custom template if you need to keep the appearance the same.

  • Removed the template argument to the table constructor, use template_name instead.

  • Stopped adding column names to the class attribute of table cells (<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)
        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)

1.21.2 (2018-03-26)

  • Moved table instantiation from get_context_data to get_tables #554 by @sdolemelipone

  • Pass request as kwarg to template.render(), rather than as part of context. (fixes #552)

1.21.1 (2018-03-12)

  • Do not perform extra COUNT() queries for non-paginated tables. Fixes #551

1.21.0 (2018-03-12)

  • Add new method paginated_rows to Table to replace fallback to non-paginated rows in templates.

  • Prevent mutation of the template context {% 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 }}.

1.20.0 (2018-03-08)

  • Define and use get_table_data in MultiTableMixin #538 by @vCra (fixes #528)

  • Added {% export_url <format> %} template tag.

  • Allow passing a TableData-derived class to the data argument of the Table constructor, instead of a QuerySet or list of dicts.

1.19.0 (2018-02-02)

  • BoundColumn.attrs does not evaluate current_value as bool #536 by @pachewise (fixes #534)

  • Allow more flexible access to cell values (especially useful for django templates) (fixes #485)

1.18.0 (2018-01-27)

  • Follow relations when detecting column type for fields in Table.Meta.fields (fixes #498)

  • Renamed Table.Meta.template to template_name (with deprecation warning for the former) #542 (fixes #520)

  • Added Czech translation #533 by @OndraRehounek

  • Added table_factory #532 by @ZuluPro

1.17.1 (2017-12-14)

  • Fix typo in for extras_require.

1.17.0 (2017-12-14)

  • Dropped support for Django 1.8, 1.9 and 1.10.

  • Add extra_context argument to TemplateColumn #509 by @ad-m

  • Remove unnecessary cast of record to str #514, fixes #511

  • Use django.test.TestCase for all tests, and remove dependency on pytest and reorganized some tests #515

  • Remove traces of django-haystack tests from the tests, there were no actual tests.

1.16.0 (2017-11-27)

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!

  • Added tf dictionary to Column.attrs with default values for the footer, so footers now have class attribute by default #501 by @mpasternak

1.15.0 (2017-11-23)

  • Added as=varname keyword argument to the {% querystring %} template tag, fixes #481

  • Updated the tutorial to reflect current state of Django a bit better.

  • Used OrderedDict rather than dict as the parent for utils.AttributeDict to make the rendered html more consistent across python versions.

  • Allow reading column 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 #500

1.14.2 (2017-10-30)

  • Added a row_counter variable to the template context in TemplateColumn (fixes #448)

1.14.1 (2017-10-30)

  • Do not fail if orderable=False is passed to ManyToManyColumn()

1.14.0 (2017-10-30)

  • Added separator argument to ManyToManyColumn.

  • Allow mark_safe()’d strings from ManyToManyColumn.tranform()

  • Disabled ordering on ManyToManyColumns by default.

1.13.0 (2017-10-17)

  • Made positional data argument to the table __init__() a keyword argument to make inheritance easier. Will raise a TypeError if omitted.

1.12.0 (2017-10-10)

1.11.0 (2017-09-15)

  • Added Hungarian translation #471 by @hmikihth.

  • Added TemplateColumn.value() and enhanced export docs (fixes #470)

  • Fixed display of pinned rows if table has no data. #477 by @khirstinova

1.10.0 (2017-06-30)

  • Added ManyToManyColumn automatically added for ManyToManyFields.

1.9.1 (2017-06-29)

  • Allow customizing the value used in Table.as_values() (when using a render_<name> method) using a value_<name> method. (fixes #458)

  • Allow excluding columns from the Table.as_values() output. (fixes #459)

  • Fixed unicode handling for column headers in Table.as_values()

1.9.0 (2017-06-22)

  • Allow computable attrs for <td>-tags from Table.attrs (#457, fixes #451)

1.8.0 (2017-06-17)

  • Feature: Added an ExportMixin to export table data in various export formats (CSV, XLS, etc.) using tablib.

  • Defer expanding Meta.sequence to Table.__init__, to make sequence work in combination with extra_columns (fixes #450)

  • Fixed a crash when MultiTableMixin.get_tables() returned an empty array (#454 by @pypetey

1.7.1 (2017-06-02)

  • Call before_render when rendering with the render_table template tag (fixes #447)

1.7.0 (2017-06-01)

  • Make title() lazy (#443 by @ygwain, fixes #438)

  • Fix __all__ by populating them with the names of the items to export instead of the items themselves.

  • Allow adding extra columns to an instance using the extra_columns argument. Fixes #403, #70

  • Added a hook before_render to allow last-minute changes to the table before rendering.

  • Added and BoundColumns.hide() to show/hide columns on an instance of a Table.

  • Use <listlike>.verbose_name/.verbose_name_plural if it exists to name the items in the list. (fixes #166)

1.6.1 (2017-05-08)

1.6.0 (2017-05-01)

  • Add new template bootstrap-responsive.html to generate a responsive bootstrap table. (Fixes #436)

1.5.0 (2017-04-18)

Full disclosure: as of april 1st, 2017, I am an employee of Zostera, as such I will continue to maintain and improve django-tables2.

  • Made TableBase.as_values() an iterator (#432 by @pziarsolo)

  • Added JSONColumn for data in JSON format.

  • Added __all__ in django_tables2/ and django_tables2/columns/

  • Added a setting DJANGO_TABLES2_TEMPLATE to allow project-wide overriding of the template used to render tables (fixes #434).

1.4.2 (2017-03-06)

  • Feature: Pinned rows (#411 by @djk2, fixes #406)

  • Fix an issue where ValueError was raised while using a view with a get_queryset() method defined. (fix with #423 by @desecho)

1.4.1 (2017-02-27)

  • Fix URLS to screenshots in on PyPi description (fixes #398)

  • Prevent superfluous spaces when a callable row_attrs['class'] returns an empty string (#417 by @Superman8218), fixes #416)

1.4.0 (2017-02-27)

  • Return None from Table.as_values() for missing values. #419

  • Fix ordering by custom fields, and refactor TableData #424, fixes #413

  • Revert removing TableData.__iter__() (removed in this commit), fixes #427, #361 and #421.

1.3.0 (2017-01-20)

  • Implement method Table.as_values() to get it’s raw values. #394 by @intiocean

  • Fix some compatibility issues with django 2.0 #408 by djk2

1.2.9 (2016-12-21)

  • Documentation for None-column attributes #401 by @dyve

1.2.8 (2016-12-21)

  • None-column attributes on child class overwrite column attributes of parent class #400 by @dyve

1.2.7 (2016-12-12)

  • Apply title to a column’s verbose_name when it is derived from a model, fixes #249. (#382 by @shawnnapora)

  • Update documentation after deprecation of STATIC_URL in django (#384, by @velaia)

  • Cleanup of the templates, making the output more equal (#381 by @ralgozino)

  • Use new location for urlresolvers in Django and add backwards compatible import (#388 by @felixxm)

  • Fix a bug where using sequence and then exclude in a child table would result in a KeyError

  • Some documentation fixes and cleanups.

1.2.6 (2016-09-06)

  • Added get_table_kwargs() method to SingleTableMixin to allow passing custom keyword arguments to the Table constructor. (#366 by @fritz-k)

  • Allow the children of TableBase render in the {% render_table %} template tag. (#377 by @shawnnapora)

  • Refactor BoundColumn attributes to allow override of CSS class names, fixes #349 (#370 by @graup). Current behavior should be intact, we will change the default in the future so it will not add the column name to the list of CSS classes.

1.2.5 (2016-07-30)

  • Fixed an issue preventing the rest of the row being rendered if a BooleanColumn was in the table for a model without custom choices defined on the model field. (#360)

1.2.4 (2016-07-28)

1.2.3 (2016-07-05)

  • Accept text parameter in FileColumn, analogous to LinkColumn (#343 by @graup)

  • Fix TemplateColumn RemovedInDjango110Warning fixes #346.

  • Use field name in RelatedColumnLink (#350, fixes #347)

v1.2.2 (2016-06-04)

  • Allow use of custom class names for ordered columns through attrs. ( #329 by @theTarkus)

  • Column ordering QuerySet pass through (#330 by @theTarkus)

  • Cleanup/restructuring of documentation, (#325)

  • Fixed an issue where explicitly defined column options where not preserved over inheritance (#339, issue #337)

  • Fixed an issue where exclude in combination with sequence raised a KeyError (#341, issue #205)

v1.2.1 (2016-05-09)

  • table footers (#323)

  • Non-field based LinkColumn only renders default value if lookup fails. (#322)

  • Accept text parameter in BaseLinkColumn-based columns. (#322)

  • Pass the table instance into SingleTableMixin’s get_table_pagination (#320 by @georgema1982, fixes #319)

  • Check if the view has paginate_by before before trying to access it. (fixes #326)

v1.2.0 (2016-05-02)

  • Allow custom attributes for rows (fixes #47)

v1.1.8 (2016-05-02)

  • Ability to change the body of the <a>-tag, by passing text kwarg to the columns inheriting from BaseLinkColumn (#318 by @desecho, #322)

  • Non-field based LinkColumn only renders default value if lookup fails and text is not set. (#322, fixes #257)

v1.1.7 (2016-04-26)

  • Added Italian translation (#315 by @paolodina

  • Added Dutch translation.

  • Fixed {% blocktrans %} template whitespace issues

  • Fixed errors when using a column named items (#316)

  • Obey paginate_by (from MultipleObjectMixin) if no later pagination is defined (#242)

v1.1.6 (2016-04-02)

  • Correct error message about request context processors for current Django (#314)

  • Skipped 1.1.5 due to an error while creating the tag.

v1.1.4 (2016-03-22)

  • Fix broken if Django is not installed before django-tables2 (fixes #312)

v1.1.3 (2016-03-21)

  • Drop support for Django 1.7

  • Add argument to CheckBoxColumn to render it as checked (original PR: #208)

v1.1.2 (2016-02-16)

  • Fix BooleanColumn with choices set will always render as if True (#301)

  • Fix a bug with TemplateColumn while using cached template loader (#75)

v1.1.1 (2016-01-26)

  • Allow Meta.fields to be a list as well as a tuple (#250)

  • Call template.render with a dict in Django >= 1.8. (#298)

  • Added RelatedLinkColumn() to render links to related objects (#297)

  • Remove default value from request parameter to table.as_html()

v1.1.0 (2016-01-19)

  • Add tests for TimeColumn

  • Remove sortable argument for Table and Column constructors and its associated methods. Deprecated since 2012.

  • Remove deprecated aliases for attrs in CheckboxColumn.

  • Remove deprecated OrderByTuple cmp method (deprecated since 2013).

  • Add bootstrap template and (#293, fixes #141, #285)

  • Fix different html for tables with and without pagination (#293, fixes #149, #285)

  • Remove {% nospaceless %} template tag and remove wrapping template in {% spaceless %} Possible breaking change, if you use custom templates.

v1.0.7 (2016-01-03)

  • Explicitly check if column.verbose_name is not None to support empty column headers (fixes #280)

  • Cleanup the example project to make it work with modern Django versions.

  • Do not sort QuerySet when orderable=False (#204 by @bmihelac)

  • show_header attribute on Table allows disabling the header (#175 by @kviktor)

  • LinkColumn now tries to call get_absolute_url on a record if no viewname is provided (#283, fixes #231).

  • Add request argument to Table.as_html() to allow passing correct request objects instead of poorly generated ones #282

  • Add coverage reporting to build #282

  • Drop support for python 3.2 (because of coverage), support ends February 2016 #282

  • move build_request from django_table2.utils to tests.utils and amend tests #282

v1.0.6 (2015-12-29)

  • Support for custom text value in LinkColumn (#277 by @toudi)

  • Refactor LinkColumn.render_link() to not escape twice #279

  • Removed Attrs (wrapper for dict), deprecated on 2012-09-18

  • Convert to rst in to make PyPI look nice (fixes #97)

v1.0.5 (2015-12-17)

  • First version released by new maintainer @jieter

  • Dropped support for Django 1.5 and 1.6, add python 3.5 with Django 1.8 and 1.9 to the build matrix (#273)

  • Prevent SingleTableView from calling get_queryset twice. (fixes #155)

  • Don’t call managers when resolving accessors. (#214 by @mbertheau, fixes #211)

v1.0.4 (2015-05-09)

  • Fix bug in retrieving field.verbose_name under Django 1.8.


  • Remove setup.cfg as PyPI does not actually support it, instead it is a distutils2 thing that is been discontinued.


  • Add setup.cfg to declare for PyPI.


  • Convert README to markdown so it’s formatted nicely on PyPI.


  • Travis CI builds pass.

  • Added Python 3.4 support.

  • Added Django 1.7 and Django 1.8 support.

  • Convert tests to using py.test.


  • Django 1.8 fixes

  • BoundColumn.verbose_name now only is capitalized only if no verbose_name was given. verbose_name is used verbatim.

  • Add max_length attribute to person CharField

  • Add Swedish translation

  • Update docs presentation on readthedocs


  • Add UK, Russian, Spanish, Portuguese, and Polish translations

  • Add support for computed table attrs.


  • querystring and seturlparam template tags now require the request to be in the context (backwards incompatible) – #127

  • Add Travis CI support

  • Add support for Django 1.5

  • Add L10N control for columns #120 (ignored in < Django 1.3)

  • Drop Python 2.6.4 support in favor of Python 3.2 support

  • Non-QuerySet data ordering is different between Python 3 and 2. When comparing different types, their truth values are now compared before falling back to string representations of their type.


  • Add FileColumn.


  • When resolving an accessor, all exceptions are smothered into None.


  • Improve performance by removing unnecessary queries

  • Simplified pagination:

    • is an instance attribute (no longer @property)

    • Exceptions raised by paginators (e.g. EmptyPage) are no longer smothered by

    • Pagination exceptions are raised by Table.paginate

    • RequestConfig can handles pagination errors silently, can be disabled by including silent=False in the paginate argument value

  • Add DateTimeColumn and DateColumn to handle formatting datetime and time zones.

  • Add BooleanColumn to handle bool values

  • render_table can now build and render a table for a QuerySet, rather than needing to be passed a table instance

  • Table columns created automatically from a model now use specialized columns

  • Column.render is now skipped if the value is considered empty, the default value is used instead. Empty values are specified via Column.empty_values, by default is (None, '') (backward incompatible)

  • Default values can now be specified on table instances or Table.Meta

  • Accessor’s now honor alters_data during resolving. Fixes issue that would delete all your data when a column had an accessor of delete

  • Add default and value to context of TemplateColumn

  • Add cardinality indication to the pagination area of a table

  • Attrs is deprecated, use dict instead


  • Add URLColumn to render URLs in a data source into hyperlinks

  • Add EmailColumn to render email addresses into hyperlinks

  • TemplateColumn can now Django’s template loaders to render from a file


  • Fix more bugs on Python 2.6.4, all tests now pass.


  • Fix issues for Python 2.6.4 – thanks Steve Sapovits & brianmay

  • Reduce Django 1.3 dependency to Table.as_html – thanks brianmay


  • Fix to include example templates, thanks TWAC.

  • Upgrade django-attest to fix problem with tests on Django 1.3.1


  • Fixed support for Django 1.4’s paginator (thanks @koledennix)

  • Some juggling of internal implementation. TableData now supports slicing and returns new TableData instances. BoundRows now takes a single argument data (a TableData instance).

  • Add support for get_pagination on SingleTableMixin.

  • SingleTableMixin and SingleTableView are now importable directly from django_tables2.


  • Renamed BoundColumn.order_by to order_by_alias and never returns None (Backwards incompatible). Templates are affected if they use something like:

    {% querystring table.prefixed_order_by_field=column.order_by.opposite| %}

    Which should be rewritten as:

    {% querystring %}
  • Added next shortcut to OrderBy returned from BoundColumn.order_by_alias

  • Added OrderByTuple.get()

  • Deprecated BoundColumn.sortable, Column.sortable, Table.sortable, sortable CSS class, BoundColumns.itersortable, BoundColumns.sortable; use orderable instead of sortable.

  • Added BoundColumn.is_ordered

  • Introduced concept of an order by alias, see glossary in the docs for details.


  • Fix bug that caused an ordered column’s <th> to have no HTML attributes.


  • Updated example project to add colspan on footer cell so table border renders correctly in Webkit.

  • Fix regression that caused ‘sortable’ class on .

  • Table.__init__ no longer always calls .order_by() on QuerySets, fixes #55. This does introduce a slight backwards incompatibility. Table.order_by now has the possibility of returning None, previously it would always return an OrderByTuple.

  • DeclarativeColumnsMetaclass.__new__ now uses `super()``

  • Testing now requires pylint and Attest >=0.5.3


  • Fix regression that caused column verbose_name values that were marked as safe to be escaped. Now any verbose_name values that are instances of SafeData are used unmodified.


  • Fix regression in SingleTableMixin.

  • Remove stray print statement.


  • SingleTableView now uses RequestConfig. This fixes issues with order_by_field, page_field, and per_page_field not being honored.

  • Add Table.Meta.per_page and change Table.paginate to use it as default.

  • Add title template filter. It differs from Django’s built-in title filter because it operates on an individual word basis and leaves words containing capitals untouched. Warning: use {% load ... from ... %} to avoid inadvertently replacing Django’s built-in title template filter.

  • BoundColumn.verbose_name no longer does capfirst, capitalizing is now the responsibility of Column.header.

  • BoundColumn.__unicode__ now uses BoundColumn.header rather than BoundColumn.verbose_name.


  • Fix version in


  • Add support for column attributes (see Attrs)

  • Add BoundRows.items() to yield (bound_column, cell) pairs

  • Tried to make docs more concise. Much stronger promotion of using RequestConfig and {% querystring %}


  • Removed random ‘print’ statements.

  • Tweaked paleblue theme css to be more flexible:

    • removed whitespace: no-wrap

    • header background image to support more than 2 rows of text


  • Fixed stupid import mistake. Tests did not pick it up due to them ignoring ImportError.


  • SingleTableView now inherits from ListView which enables automatic foo_list.html template name resolution (thanks dramon for reporting)

  • render_table template tag no suppresses exceptions when DEBUG=True


  • Fixed bug in render_table when giving it a template (issue #41)


  • Added translation support in the default template via {% trans %}

  • Removed basic_table.html, Table.as_html() now renders table.html but will clobber the query string of the current request. Use the render_table template tag instead

  • render_table now supports an optional second argument – the template to use when rendering the table

  • Table now supports declaring which template to use when rendering to HTML

  • Django >=1.3 is now required

  • Added support for using django-haystack’s SearchQuerySet as a data source

  • The default template table.html now includes block tags to make it easy to extend to change small pieces

  • Fixed table template parsing problems being hidden due to a subsequent exception being raised

  • Http404 exceptions are no longer raised during a call to Table.paginate(), instead it now occurs when is accessed

  • Fixed bug where a table could not be rendered more than once if it was paginated.

  • Accessing now returns a new page every time, rather than reusing a single object


  • Tables now support using both sequence and exclude (issue #32).

  • Sequence class moved to django_tables2/

  • Table instances now support modification to the exclude property.

  • Removed BoundColumns._spawn_columns.

  •, Table.rows, and Table.columns are now attributes rather than properties.