diff --git a/src/wuttaweb/grids/base.py b/src/wuttaweb/grids/base.py index 1d99a9f..077f51a 100644 --- a/src/wuttaweb/grids/base.py +++ b/src/wuttaweb/grids/base.py @@ -2415,6 +2415,15 @@ class Grid: # pylint: disable=too-many-instance-attributes,too-many-public-meth except TypeError: dct = dict(obj.__dict__) dct.pop("_sa_instance_state", None) + + # nb. inject association proxy(-like) fields if applicable + for field in self.columns: + if field not in dct: + try: + dct[field] = getattr(obj, field) + except AttributeError: + pass + return dct def get_vue_context(self): diff --git a/tests/grids/test_base.py b/tests/grids/test_base.py index d98282f..89c0f50 100644 --- a/tests/grids/test_base.py +++ b/tests/grids/test_base.py @@ -1923,10 +1923,24 @@ class TestGrid(WebTestCase): def __init__(self, **kw): self.__dict__.update(kw) + def __getattr__(self, name): + if name == "something": + return "else" + raise AttributeError(f"attr not found: {name}") + mock = MockSetting(**setting) dct = grid.object_to_dict(mock) self.assertIsInstance(dct, dict) self.assertEqual(dct, setting) + self.assertNotIn("something", dct) + + # test (mock) association proxy behavior + grid.columns.append("something") + grid.columns.append("another") + dct = grid.object_to_dict(mock) + self.assertIn("something", dct) + self.assertEqual(dct["something"], "else") + self.assertNotIn("another", dct) def test_get_vue_context(self):