diff --git a/src/wuttaweb/grids/base.py b/src/wuttaweb/grids/base.py index c2f3156..fb797a4 100644 --- a/src/wuttaweb/grids/base.py +++ b/src/wuttaweb/grids/base.py @@ -602,6 +602,7 @@ class Grid: * ``'batch_id'`` -> :meth:`render_batch_id()` * ``'boolean'`` -> :meth:`render_boolean()` * ``'currency'`` -> :meth:`render_currency()` + * ``'date'`` -> :meth:`render_date()` * ``'datetime'`` -> :meth:`render_datetime()` * ``'quantity'`` -> :meth:`render_quantity()` @@ -611,6 +612,7 @@ class Grid: 'batch_id': self.render_batch_id, 'boolean': self.render_boolean, 'currency': self.render_currency, + 'date': self.render_date, 'datetime': self.render_datetime, 'quantity': self.render_quantity, } @@ -631,11 +633,13 @@ class Grid: data type implies a default renderer. This is only possible if :attr:`model_class` is set to a SQLAlchemy mapped class. - This only looks for a couple of data types, and configures as + This only looks for a few data types, and configures as follows: * :class:`sqlalchemy:sqlalchemy.types.Boolean` -> :meth:`render_boolean()` + * :class:`sqlalchemy:sqlalchemy.types.Date` -> + :meth:`render_date()` * :class:`sqlalchemy:sqlalchemy.types.DateTime` -> :meth:`render_datetime()` """ @@ -651,7 +655,9 @@ class Grid: prop = getattr(attr, 'prop', None) if prop and isinstance(prop, orm.ColumnProperty): column = prop.columns[0] - if isinstance(column.type, sa.DateTime): + if isinstance(column.type, sa.Date): + self.set_renderer(key, self.render_date) + elif isinstance(column.type, sa.DateTime): self.set_renderer(key, self.render_datetime) elif isinstance(column.type, sa.Boolean): self.set_renderer(key, self.render_boolean) @@ -1820,7 +1826,7 @@ class Grid: This may be used automatically per :meth:`set_default_renderers()` or you can use it explicitly:: - grid.set_renderer('foo', grid.render_boolean) + grid.set_renderer('foo', 'boolean') """ return self.app.render_boolean(value) @@ -1839,6 +1845,22 @@ class Grid: """ return self.app.render_currency(value, **kwargs) + def render_date(self, obj, key, value): + """ + Column renderer for :class:`python:datetime.date` values. + + This calls + :meth:`~wuttjamaican:wuttjamaican.app.AppHandler.render_date()` + for the return value. + + This may be used automatically per + :meth:`set_default_renderers()` or you can use it explicitly:: + + grid.set_renderer('foo', 'date') + """ + dt = getattr(obj, key) + return self.app.render_date(dt) + def render_datetime(self, obj, key, value): """ Column renderer for :class:`python:datetime.datetime` values. @@ -1850,7 +1872,7 @@ class Grid: This may be used automatically per :meth:`set_default_renderers()` or you can use it explicitly:: - grid.set_renderer('foo', grid.render_datetime) + grid.set_renderer('foo', 'datetime') """ dt = getattr(obj, key) return self.app.render_datetime(dt) @@ -1865,7 +1887,7 @@ class Grid: This is not used automatically but you can use it explicitly:: - grid.set_renderer('foo', grid.render_quantity) + grid.set_renderer('foo', 'quantity') """ return self.app.render_quantity(value) diff --git a/tests/grids/test_base.py b/tests/grids/test_base.py index 0cccbeb..d5f3766 100644 --- a/tests/grids/test_base.py +++ b/tests/grids/test_base.py @@ -213,7 +213,7 @@ class TestGrid(WebTestCase): obj = MagicMock(foo=42.00) self.assertEqual(grid.renderers['foo'](obj, 'foo', 42.00), '42') - def test_set_default_renderer(self): + def test_set_default_renderers(self): model = self.app.model # no defaults for "plain" schema @@ -249,6 +249,18 @@ class TestGrid(WebTestCase): self.assertIn('executing', grid.renderers) self.assertIs(grid.renderers['executing'], myrender) + # nb. as of writing we have no Date columns in default schema, + # so must invent one to test that type + class SomeFoolery(model.Base): + __tablename__ = 'somefoolery' + id = sa.Column(sa.Integer(), primary_key=True) + created = sa.Column(sa.Date()) + + # renderer set for date mapped field + grid = self.make_grid(model_class=SomeFoolery) + self.assertIn('created', grid.renderers) + self.assertIsNot(grid.renderers['created'], myrender) + def test_linked_columns(self): grid = self.make_grid(columns=['foo', 'bar']) self.assertEqual(grid.linked_columns, []) @@ -1415,6 +1427,20 @@ class TestGrid(WebTestCase): # zero is *not* empty string (with this renderer) self.assertEqual(grid.render_quantity(obj, 'foo', 0), "0") + def test_render_date(self): + grid = self.make_grid(columns=['foo', 'bar']) + + # null + obj = MagicMock(dt=None) + result = grid.render_date(obj, 'dt', None) + self.assertIsNone(result) + + # typical + dt = datetime.date(2025, 1, 13) + obj = MagicMock(dt=dt) + result = grid.render_date(obj, 'dt', str(dt)) + self.assertEqual(result, '2025-01-13') + def test_render_datetime(self): grid = self.make_grid(columns=['foo', 'bar'])