"""Overridden. The snapshot in this case is simply a queryset\r
with the necessary filters etc. attached.\r
"""\r
+\r
+ # reset caches\r
+ self._columns._reset()\r
+ self._rows = None\r
+\r
queryset = self.queryset\r
if self.order_by:\r
queryset = queryset.order_by(*self._cols_to_fields(self.order_by))\r
In the case of this base table implementation, a copy of the\r
source data is created, and then modified appropriately.\r
"""\r
+\r
+ # reset caches\r
+ self._columns._reset()\r
+ self._rows = None\r
+\r
snapshot = copy.copy(self._data)\r
for row in snapshot:\r
# delete unknown columns that are in the source data, but that\r
def as_html(self):\r
pass\r
\r
+ def update(self):\r
+ """Update the table based on it's current options.\r
+\r
+ Normally, you won't have to call this method, since the table\r
+ updates itself (it's caches) automatically whenever you change\r
+ any of the properties. However, in some rare cases those\r
+ changes might not be picked up, for example if you manually\r
+ change ``base_columns`` or any of the columns in it.\r
+ """\r
+ self._build_snapshot()\r
+\r
class Table(BaseTable):\r
"A collection of columns, plus their associated data rows."\r
# This is a separate class from BaseTable in order to abstract the way\r
self.table = table\r
self._columns = SortedDict()\r
\r
+ def _reset(self):\r
+ """Used by parent table class."""\r
+ self._columns = SortedDict()\r
+\r
def _spawn_columns(self):\r
# (re)build the "_columns" cache of BoundColumn objects (note that\r
# ``base_columns`` might have changed since last time); creating\r
books.base_columns['test'] = tables.Column()\r
assert not 'test' in BookTable.base_columns\r
\r
- # make sure the row and column caches work\r
- assert id(list(books.columns)[0]) == id(list(books.columns)[0])\r
- # TODO: row cache currently not used\r
- #assert id(list(books.rows)[0]) == id(list(books.rows)[0])\r
-\r
# optionally, exceptions can be raised when input is invalid\r
tables.options.IGNORE_INVALID_OPTIONS = False\r
raises(Exception, "books.order_by = '-name,made-up-column'")\r
# reset for future tests\r
tables.options.IGNORE_INVALID_OPTIONS = True\r
\r
+def test_caches():\r
+ """Ensure the various caches are effective.\r
+ """\r
+\r
+ class BookTable(tables.Table):\r
+ name = tables.Column()\r
+ answer = tables.Column(default=42)\r
+ books = BookTable([\r
+ {'name': 'Foo: Bar'},\r
+ ])\r
+\r
+ assert id(list(books.columns)[0]) == id(list(books.columns)[0])\r
+ # TODO: row cache currently not used\r
+ #assert id(list(books.rows)[0]) == id(list(books.rows)[0])\r
+\r
+ # test that caches are reset after an update()\r
+ old_column_cache = id(list(books.columns)[0])\r
+ old_row_cache = id(list(books.rows)[0])\r
+ books.update()\r
+ assert id(list(books.columns)[0]) != old_column_cache\r
+ assert id(list(books.rows)[0]) != old_row_cache\r
+\r
def test_sort():\r
class BookTable(tables.Table):\r
id = tables.Column()\r
countries = CountryTable(Country)\r
test_country_table(countries)\r
\r
- # make sure the row and column caches work for model tables as well\r
+def test_caches():\r
+ """Make sure the caches work for model tables as well (parts are\r
+ reimplemented).\r
+ """\r
+ class CountryTable(tables.ModelTable):\r
+ class Meta:\r
+ model = Country\r
+ exclude = ('id',)\r
+ countries = CountryTable()\r
+\r
assert id(list(countries.columns)[0]) == id(list(countries.columns)[0])\r
# TODO: row cache currently not used\r
#assert id(list(countries.rows)[0]) == id(list(countries.rows)[0])\r
\r
+ # test that caches are reset after an update()\r
+ old_column_cache = id(list(countries.columns)[0])\r
+ old_row_cache = id(list(countries.rows)[0])\r
+ countries.update()\r
+ assert id(list(countries.columns)[0]) != old_column_cache\r
+ assert id(list(countries.rows)[0]) != old_row_cache\r
+\r
def test_sort():\r
class CountryTable(tables.ModelTable):\r
tld = tables.Column(name="domain")\r
\r
# TODO: pagination\r
# TODO: support function column sources both for modeltables (methods on model) and static tables (functions in dict)\r
-# TODO: manual base columns change -> update() call (add as example in docstr here) -> rebuild snapshot: is row cache, column cache etc. reset?\r
# TODO: support relationship spanning columns (we could generate select_related() automatically)
\ No newline at end of file