From ec18ce7116a3f70a097c7c3a35908f572980e0a4 Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Fri, 20 Feb 2026 14:35:43 -0600 Subject: [PATCH] fix: allow passing filter factory to `Grid.set_filter()` --- src/wuttaweb/grids/base.py | 34 +++++++++++++++++++++------------- tests/grids/test_base.py | 7 +++++-- 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/src/wuttaweb/grids/base.py b/src/wuttaweb/grids/base.py index 0cc8f3f..2ac2646 100644 --- a/src/wuttaweb/grids/base.py +++ b/src/wuttaweb/grids/base.py @@ -1404,10 +1404,11 @@ class Grid: # pylint: disable=too-many-instance-attributes,too-many-public-meth Code usually does not need to call this directly. See also :meth:`set_filter()`, which calls this method automatically. - :param columninfo: Can be either a model property (see below), - or a column name. + :param columninfo: Can be either a model property + (e.g. ``model.User.username``), or a column name + (e.g. ``"username"``). - :returns: A :class:`~wuttaweb.grids.filters.GridFilter` + :returns: :class:`~wuttaweb.grids.filters.GridFilter` instance. """ key = kwargs.pop("key", None) @@ -1445,12 +1446,18 @@ class Grid: # pylint: disable=too-many-instance-attributes,too-many-public-meth :param key: Name of column. - :param filterinfo: Can be either a - :class:`~wuttweb.grids.filters.GridFilter` instance, or - else a model property (see below). + :param filterinfo: Can be either a filter factory, or else a + model property (e.g. ``model.User.username``) or column + name (e.g. ``"username"``). If not specified then the + ``key`` will be used instead. - If ``filterinfo`` is a ``GridFilter`` instance, it will be - used as-is for the backend filter. + :param \\**kwargs: Additional kwargs to pass along to the + filter factory. + + If ``filterinfo`` is a factory, it will be called with the + current request, key and kwargs like so:: + + filtr = factory(self.request, key, **kwargs) Otherwise :meth:`make_filter()` will be called to obtain the backend filter. The ``filterinfo`` will be passed along to @@ -1462,12 +1469,13 @@ class Grid: # pylint: disable=too-many-instance-attributes,too-many-public-meth filtr = None if filterinfo and callable(filterinfo): - # filtr = filterinfo - raise NotImplementedError + kwargs.setdefault("label", self.get_filter_label(key)) + filtr = filterinfo(self.request, key, **kwargs) - kwargs["key"] = key - kwargs.setdefault("label", self.get_label(key)) - filtr = self.make_filter(filterinfo or key, **kwargs) + else: + kwargs["key"] = key + kwargs.setdefault("label", self.get_filter_label(key)) + filtr = self.make_filter(filterinfo or key, **kwargs) self.filters[key] = filtr diff --git a/tests/grids/test_base.py b/tests/grids/test_base.py index 3dd8208..1e193ea 100644 --- a/tests/grids/test_base.py +++ b/tests/grids/test_base.py @@ -1310,10 +1310,13 @@ class TestGrid(WebTestCase): grid.set_filter("name") self.assertIn("name", grid.filters) - # explicit is not yet implemented + # auto from filter factory grid = self.make_grid(model_class=model.Setting) self.assertEqual(grid.filters, {}) - self.assertRaises(NotImplementedError, grid.set_filter, "name", lambda q: q) + grid.set_filter( + "name", StringAlchemyFilter, model_property=model.Setting.name + ) + self.assertIn("name", grid.filters) def test_remove_filter(self): model = self.app.model