# -*- coding: utf-8 -*-
from django.utils.safestring import EscapeUnicode, SafeData
+from .proxies import TemplateSafeLazyProxy
+import itertools
class BoundRow(object):
- """Represents a *specific* row in a table.
+ """
+ Represents a *specific* row in a table.
- :class:`BoundRow` objects are a container that make it easy to access the
+ :class:`.BoundRow` objects are a container that make it easy to access the
final 'rendered' values for cells in a row. You can simply iterate over a
- :class:`BoundRow` object and it will take care to return values rendered
- using the correct method (e.g. :meth:`Column.render_FOO`)
+ :class:`.BoundRow` object and it will take care to return values rendered
+ using the correct method (e.g. :meth:`.Column.render_FOO`)
To access the rendered value of each cell in a row, just iterate over it:
...
KeyError: 'c'
+ :param table: is the :class:`Table` in which this row exists.
+ :param record: a single record from the :term:`table data` that is used to
+ populate the row. A record could be a :class:`Model` object, a
+ :class:`dict`, or something else.
+
"""
def __init__(self, table, record):
- """Initialise a new :class:`BoundRow` object where:
-
- * *table* is the :class:`Table` in which this row exists.
- * *record* is a single record from the data source that is posed to
- populate the row. A record could be a :class:`Model` object, a
- ``dict``, or something else.
-
- """
self._table = table
self._record = record
@property
def table(self):
- """The associated :term:`table`."""
+ """The associated :class:`.Table` object."""
return self._table
@property
def record(self):
- """The data record from the data source which is used to populate this
- row with data.
+ """
+ The data record from the data source which is used to populate this row
+ with data.
"""
return self._record
def __iter__(self):
- """Iterate over the rendered values for cells in the row.
+ """
+ Iterate over the rendered values for cells in the row.
- Under the hood this method just makes a call to :meth:`__getitem__` for
- each cell.
+ Under the hood this method just makes a call to
+ :meth:`.BoundRow.__getitem__` for each cell.
"""
for column in self.table.columns:
yield self[column.name]
def __getitem__(self, name):
- """Returns the final rendered value for a cell in the row, given the
- name of a column.
+ """
+ Returns the final rendered value for a cell in the row, given the name
+ of a column.
"""
bound_column = self.table.columns[name]
- raw = bound_column.accessor.resolve(self.record)
+
+ def value():
+ try:
+ raw = bound_column.accessor.resolve(self.record)
+ except (TypeError, AttributeError, KeyError, ValueError) as e:
+ raw = None
+ return raw if raw is not None else bound_column.default
+
kwargs = {
- 'value': raw if raw is not None else bound_column.default,
+ 'value': TemplateSafeLazyProxy(value),
'record': self.record,
'column': bound_column.column,
'bound_column': bound_column,
"""
Container for spawning :class:`.BoundRow` objects.
- The :attr:`.tables.Table.rows` attribute is a :class:`.BoundRows` object.
+ The :attr:`.Table.rows` attribute is a :class:`.BoundRows` object.
It provides functionality that would not be possible with a simple iterator
in the table class.
+ :type table: :class:`.Table` object
+ :param table: the table in which the rows exist.
+
"""
def __init__(self, table):
- """
- Initialise a :class:`Rows` object. *table* is the :class:`Table` object
- in which the rows exist.
-
- """
self.table = table
def all(self):
"""
- Return an iterable for all :class:`BoundRow` objects in the table.
+ Return an iterable for all :class:`.BoundRow` objects in the table.
"""
for record in self.table.data:
def page(self):
"""
If the table is paginated, return an iterable of :class:`.BoundRow`
- objects that appear on the current page, otherwise :const:`None`.
+ objects that appear on the current page.
+ :rtype: iterable of :class:`.BoundRow` objects, or :const:`None`.
"""
if not hasattr(self.table, 'page'):
return None
def __getitem__(self, key):
"""Allows normal list slicing syntax to be used."""
if isinstance(key, slice):
- result = list()
- for row in self.table.data[key]:
- result.append(BoundRow(self.table, row))
- return result
+ return itertools.imap(lambda record: BoundRow(self.table, record),
+ self.table.data[key])
elif isinstance(key, int):
return BoundRow(self.table, self.table.data[key])
else: