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