diff --git a/django_tables2/tables.py b/django_tables2/tables.py index 2758ad4..01a0671 100644 --- a/django_tables2/tables.py +++ b/django_tables2/tables.py @@ -6,6 +6,7 @@ from .rows import BoundRows from .utils import (Accessor, AttributeDict, build_request, cached_property, computed_values, OrderBy, OrderByTuple, segment, Sequence) import copy +import sys from django.core.paginator import Paginator from django.db.models.fields import FieldDoesNotExist from django.utils.datastructures import SortedDict @@ -34,12 +35,15 @@ class TableData(object): self.queryset = data # otherwise it must be convertable to a list else: - try: + # do some light validation + if hasattr(data, '__iter__') or (hasattr(data, '__len__') and hasattr(data, '__getitem__')): self.list = list(data) - except: - raise ValueError('data must be QuerySet-like (have count and ' - 'order_by) or support list(data) -- %s has ' - 'neither' % type(data).__name__) + else: + raise ValueError( + 'data must be QuerySet-like (have count and ' + 'order_by) or support list(data) -- %s has ' + 'neither' % type(data).__name__ + ) def __len__(self): if not hasattr(self, "_length"): diff --git a/tests/core.py b/tests/core.py index 0a4dce2..66351e2 100644 --- a/tests/core.py +++ b/tests/core.py @@ -178,7 +178,30 @@ def should_support_haystack_data_source(): table = PersonTable(SearchQuerySet().all()) table.as_html() + + +@core.test +def data_validation(): + with raises(ValueError): + table = OrderedTable(None) + + class Bad: + def __len__(self): + pass + + with raises(ValueError): + table = OrderedTable(Bad()) + class Ok: + def __len__(self): + return 1 + def __getitem__(self, pos): + if pos != 0: + raise IndexError() + return {'a': 1} + + table = OrderedTable(Ok()) + assert len(table.rows) == 1 @core.test def ordering():