needed for).\r
\r
\r
+Table Options\r
+-------------\r
+\r
+Table-specific options are implemented using the same inner ``Meta`` class\r
+concept as known from forms and models in Django:\r
+\r
+ class MyTable(tables.Table):\r
+ class Meta:\r
+ sortable = True\r
+\r
+Currently, for non-model tables, the only supported option is ``sortable``.\r
+Per default, all columns are sortable, unless a column specifies otherwise.\r
+This meta option allows you to overwrite the global default for the table.\r
+\r
+\r
ModelTables\r
-----------\r
\r
creation_counter = 0\r
\r
def __init__(self, verbose_name=None, name=None, default=None, data=None,\r
- visible=True, inaccessible=False, sortable=True):\r
+ visible=True, inaccessible=False, sortable=None):\r
self.verbose_name = verbose_name\r
self.name = name\r
self.default = default\r
from django.core.exceptions import FieldError\r
from django.utils.datastructures import SortedDict\r
from tables import BaseTable, DeclarativeColumnsMetaclass, \\r
- Column, BoundRow, Rows\r
+ Column, BoundRow, Rows, TableOptions\r
\r
__all__ = ('BaseModelTable', 'ModelTable')\r
\r
-class ModelTableOptions(object):\r
+class ModelTableOptions(TableOptions):\r
def __init__(self, options=None):\r
+ super(ModelTableOptions, self).__init__()\r
self.model = getattr(options, 'model', None)\r
self.columns = getattr(options, 'columns', None)\r
self.exclude = getattr(options, 'exclude', None)\r
instructions.append((o, False,))\r
data.sort(cmp=_cmp)\r
\r
+class TableOptions(object):\r
+ def __init__(self, options=None):\r
+ super(TableOptions, self).__init__()\r
+ self.sortable = getattr(options, 'sortable', None)\r
+\r
class DeclarativeColumnsMetaclass(type):\r
"""\r
Metaclass that converts Column attributes to a dictionary called\r
attrs['base_columns'] = SortedDict()\r
attrs['base_columns'].update(SortedDict(columns))\r
\r
+ attrs['_meta'] = TableOptions(attrs.get('Meta', None))\r
return type.__new__(cls, name, bases, attrs)\r
\r
def rmprefix(s):\r
"""\r
if purpose == 'order_by':\r
return name in self.columns and\\r
- self.columns[name].column.sortable\r
+ self.columns[name].sortable\r
else:\r
return True\r
\r
self.column = column\r
self.declared_name = name\r
# expose some attributes of the column more directly\r
- self.sortable = column.sortable\r
self.visible = column.visible\r
\r
+ def _get_sortable(self):\r
+ if self.column.sortable is not None:\r
+ return self.column.sortable\r
+ elif self.table._meta.sortable is not None:\r
+ return self.table._meta.sortable\r
+ else:\r
+ return True # the default value\r
+ sortable = property(_get_sortable)\r
+\r
name = property(lambda s: s.column.name or s.declared_name)\r
name_reversed = property(lambda s: "-"+s.name)\r
def _get_name_toggled(self):\r
assert id(list(books.columns)[0]) != old_column_cache\r
assert id(list(books.rows)[0]) != old_row_cache\r
\r
+def test_meta_sortable():\r
+ """Specific tests for sortable table meta option."""\r
+\r
+ def mktable(default_sortable):\r
+ class BookTable(tables.Table):\r
+ id = tables.Column(sortable=True)\r
+ name = tables.Column(sortable=False)\r
+ author = tables.Column()\r
+ class Meta:\r
+ sortable = default_sortable\r
+ return BookTable([])\r
+\r
+ global_table = mktable(None)\r
+ for default_sortable, results in (\r
+ (None, (True, False, True)), # last bool is global default\r
+ (True, (True, False, True)), # last bool is table default\r
+ (False, (True, False, False)), # last bool is table default\r
+ ):\r
+ books = mktable(default_sortable)\r
+ assert [c.sortable for c in books.columns] == list(results)\r
+\r
+ # it also works if the meta option is manually changed after\r
+ # class and instance creation\r
+ global_table._meta.sortable = default_sortable\r
+ assert [c.sortable for c in global_table.columns] == list(results)\r
+\r
def test_sort():\r
class BookTable(tables.Table):\r
id = tables.Column()\r