diff --git a/osc/util/models.py b/osc/util/models.py index 525540be..7f03bacc 100644 --- a/osc/util/models.py +++ b/osc/util/models.py @@ -249,8 +249,18 @@ class Field(property): def get(self, obj): try: result = obj._values[self.name] + + # convert dictionaries into objects + # we can't do it earlier because list is a standalone object that is not under our control + if result is not None and self.is_model_list: + for num, i in enumerate(result): + if isinstance(i, dict): + klass = self.inner_type + result[num] = klass(**i) + if self.get_callback is not None: result = self.get_callback(obj, result) + return result except KeyError: pass diff --git a/tests/test_models.py b/tests/test_models.py index 89f9d981..84ae542b 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -339,6 +339,19 @@ class Test(unittest.TestCase): m.field = [{"text": "one"}, {"text": "two"}] self.assertFalse(m.has_changed()) + def test_append_dict(self): + class TestSubmodel(BaseModel): + text: str = Field(default="default") + + class TestModel(BaseModel): + field: Optional[List[TestSubmodel]] = Field(default=[]) + + m = TestModel() + m.field.append({"text": "value"}) + # dict is converted to object next time the field is retrieved + self.assertIsInstance(m.field[0], BaseModel) + self.assertEqual(m.field[0].text, "value") + if __name__ == "__main__": unittest.main()