+django-tables\r
+=============\r
+\r
+Installation\r
+------------\r
+\r
+Adding django-tables to your INSTALLED_APPS settings is optional, it'll get\r
+you the ability to load some template utilities via {% load tables %}, but\r
+apart from that, ``import django_tables as tables`` should get you going.\r
+\r
+Running the test suite\r
+----------------------\r
+\r
+The test suite uses py.test (from http://codespeak.net/py/dist/test.html).\r
+\r
Tables and Pagination\r
---------------------\r
\r
__all__ = (\r
- 'Column',\r
+ 'Column', 'TextColumn', 'NumberColumn',\r
)\r
\r
class Column(object):\r
self.default = default\r
self.visible = visible\r
self.sortable = sortable\r
- \r
+\r
self.creation_counter = Column.creation_counter\r
Column.creation_counter += 1\r
\r
-from tables import BaseTable, DeclarativeColumnsMetaclass\r
+from django.utils.datastructures import SortedDict\r
+from tables import BaseTable, DeclarativeColumnsMetaclass, Column\r
\r
__all__ = ('BaseModelTable', 'ModelTable')\r
\r
field_list = []\r
opts = model._meta\r
for f in opts.fields + opts.many_to_many:\r
- if (fields and not f.name in fields) or \\r
+ if (columns and not f.name in columns) or \\r
(exclude and f.name in exclude):\r
continue\r
column = Column()\r
# if a model is defined, then build a list of default columns and\r
# let the declared columns override them.\r
if opts.model:\r
- columns = columns_for_model(opts.model, opts.fields, opts.exclude)\r
+ columns = columns_for_model(opts.model, opts.columns, opts.exclude)\r
columns.update(self.declared_columns)\r
self.base_columns = columns\r
return self\r
--- /dev/null
+# make django-tables available for import for tests\r
+import os, sys\r
+sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
\ No newline at end of file
-from django.core.paginator import Paginator\r
-import os, sys\r
-sys.path.append(os.path.join(os.path.dirname(__file__), '..'))\r
+"""Test the base table functionality.\r
+\r
+This includes the core, as well as static data, non-model tables.\r
+"""\r
\r
import django_tables as tables\r
\r
assert 'motto' in StateTable1.base_columns\r
assert 'motto' in StateTable2.base_columns\r
\r
- # test more with actual models\r
\r
def test_basic():\r
class BookTable(tables.Table):\r
books.columns['language'].sortable = False\r
books.order_by = 'language'\r
assert not books.order_by\r
- test_order(('language', 'pages'), [1,3,2,4]) # as if: 'pages'\r
-\r
-def test_for_templates():\r
- class BookTable(tables.Table):\r
- id = tables.Column()\r
- name = tables.Column()\r
- books = BookTable([\r
- {'id': 1, 'name': 'Foo: Bar'},\r
- ])\r
-\r
- # cast to a string we get a value ready to be passed to the querystring\r
- books.order_by = ('name',)\r
- assert str(books.order_by) == 'name'\r
- books.order_by = ('name', '-id')\r
- assert str(books.order_by) == 'name,-id'\r
-\r
-test_declaration()\r
-test_basic()\r
-test_sort()\r
-test_for_templates()\r
-\r
-\r
-"""\r
-<table>\r
-<tr>\r
- {% for column in book.columns %}\r
- <th><a href="{{ column.name }}">{{ column }}</a></th\r
- <th><a href="{% set_url_param "sort" column.name }}">{{ column }}</a></th\r
- {% endfor %}\r
-</tr>\r
-{% for row in book %}\r
- <tr>\r
- {% for value in row %}\r
- <td>{{ value }]</td>\r
- {% endfor %}\r
- </tr>\r
-{% endfor %}\r
-</table>\r
-\r
-OR:\r
-\r
-<table>\r
-{% for row in book %}\r
- <tr>\r
- {% if book.columns.name.visible %}\r
- <td>{{ row.name }]</td>\r
- {% endif %}\r
- {% if book.columns.score.visible %}\r
- <td>{{ row.score }]</td>\r
- {% endif %}\r
- </tr>\r
-{% endfor %}\r
-</table>\r
-\r
-\r
-"""
\ No newline at end of file
+ test_order(('language', 'pages'), [1,3,2,4]) # as if: 'pages'
\ No newline at end of file
--- /dev/null
+"""Test ModelTable specific functionality.\r
+\r
+Sets up a temporary Django project using a memory SQLite database.\r
+"""\r
+\r
+from django.conf import settings\r
+\r
+def setup_module(module):\r
+ settings.configure(**{\r
+ 'DATABASE_ENGINE': 'sqlite3',\r
+ 'DATABASE_NAME': ':memory:',\r
+ })\r
+\r
+ from django.db import models\r
+\r
+ class City(models.Model):\r
+ name = models.TextField()\r
+ population = models.IntegerField()\r
+ module.City = City\r
+\r
+ class Country(models.Model):\r
+ name = models.TextField()\r
+ population = models.IntegerField()\r
+ capital = models.ForeignKey(City)\r
+ tld = models.TextField(verbose_name='Domain Extension', max_length=2)\r
+ module.Country = Country\r
+\r
+\r
+def test_nothing():\r
+ pass\r
+\r
+import django_tables as tables\r
+\r
+def test_declaration():\r
+ """Test declaration, declared columns and default model field columns.\r
+ """\r
+\r
+ class CountryTable(tables.ModelTable):\r
+ class Meta:\r
+ model = Country\r
+\r
+ assert len(CountryTable.base_columns) == 5\r
+ assert 'name' in CountryTable.base_columns\r
+ assert not hasattr(CountryTable, 'name')\r
+\r
+ # Override one model column, add another custom one, exclude one\r
+ class CountryTable(tables.ModelTable):\r
+ capital = tables.TextColumn(verbose_name='Name of capital')\r
+ projected = tables.Column(verbose_name="Projected Population")\r
+ class Meta:\r
+ model = Country\r
+ exclude = ['tld']\r
+\r
+ assert len(CountryTable.base_columns) == 5\r
+ assert 'projected' in CountryTable.base_columns\r
+ assert 'capital' in CountryTable.base_columns\r
+ assert not 'tld' in CountryTable.base_columns\r
+\r
+ # Inheritance (with a different model) + field restrictions\r
+ class CityTable(CountryTable):\r
+ class Meta:\r
+ model = City\r
+ columns = ['id', 'name']\r
+ exclude = ['capital']\r
+\r
+ print CityTable.base_columns\r
+ assert len(CityTable.base_columns) == 4\r
+ assert 'id' in CityTable.base_columns\r
+ assert 'name' in CityTable.base_columns\r
+ assert 'projected' in CityTable.base_columns # declared in parent\r
+ assert not 'population' in CityTable.base_columns # not in Meta:columns\r
+ assert 'capital' in CityTable.base_columns # in exclude, but only works on model fields (is that the right behaviour?)
\ No newline at end of file
--- /dev/null
+"""Test template specific functionality.\r
+\r
+Make sure tables expose their functionality to templates right.\r
+"""\r
+\r
+import django_tables as tables\r
+\r
+def test_for_templates():\r
+ class BookTable(tables.Table):\r
+ id = tables.Column()\r
+ name = tables.Column()\r
+ books = BookTable([\r
+ {'id': 1, 'name': 'Foo: Bar'},\r
+ ])\r
+\r
+ # cast to a string we get a value ready to be passed to the querystring\r
+ books.order_by = ('name',)\r
+ assert str(books.order_by) == 'name'\r
+ books.order_by = ('name', '-id')\r
+ assert str(books.order_by) == 'name,-id'\r
+\r
+\r
+"""\r
+<table>\r
+<tr>\r
+ {% for column in book.columns %}\r
+ <th><a href="{{ column.name }}">{{ column }}</a></th\r
+ <th><a href="{% set_url_param "sort" column.name }}">{{ column }}</a></th\r
+ {% endfor %}\r
+</tr>\r
+{% for row in book %}\r
+ <tr>\r
+ {% for value in row %}\r
+ <td>{{ value }]</td>\r
+ {% endfor %}\r
+ </tr>\r
+{% endfor %}\r
+</table>\r
+\r
+OR:\r
+\r
+<table>\r
+{% for row in book %}\r
+ <tr>\r
+ {% if book.columns.name.visible %}\r
+ <td>{{ row.name }]</td>\r
+ {% endif %}\r
+ {% if book.columns.score.visible %}\r
+ <td>{{ row.score }]</td>\r
+ {% endif %}\r
+ </tr>\r
+{% endfor %}\r
+</table>\r
+\r
+\r
+"""
\ No newline at end of file