Using multiple Model as alterantive?
Hi!
I'm trying to find a way to allow various Model as altenatives to handle and validate a field. I thought about UnionType or PolyModelType but I can't make them work.
Here's a sample:
class AlternativeAForm(Model):
author = StringType(required=False)
class AlternativeBForm(Model):
user = StringType(required=False)
class AlternativeCForm(Model):
owner = StringType(required=False)
class OriginalForm(Model):
email = StringType(required=True)
name = UnionType([ModelType(AlternativeAForm), ModelType(AlternativeBForm), ModelType(AlternativeCForm)])
This would accept JSON post like
{"email": "...", "name": {"author": "..."}}
or
{"email": "...", "name": {"user": "..."}}
or
{"email": "...", "name": {"owner": "..."}}
(My usage is more advanced than this example of course ;) ).
I haven't found where I could ask for help so I'm asking here, hope that's alright!
Best,
@cnicodeme Did you ever figure out a workaround to this?
@naphta No. When I'll have the time, I'll write my own library. Expect it to be ready around the year 2521
@cnicodeme I think I've figured out the issue with using multiple model types; seems to be a bug in the UnionType code.
< from ..exceptions import ConversionError
---
> from ..exceptions import ConversionError, DataError
40d39
<
51,52c50,51
< self._types[type_.__class__] = type_
< self.typenames = tuple((cls.__name__ for cls in self._types))
---
> self._types[repr(type_)] = type_
> self.typenames = tuple((cls for cls in self._types))
60c59
< except ConversionError:
---
> except (ConversionError, DataError):
72c71
< except ConversionError:
---
> except (ConversionError, DataError):
that's the diff of what I'm currently testing; basically the ModelType wasn't raising ConversionError, and when the types were being set on __init__ they were being added to a dictionary with type_.__class__ which always resolved to <class 'schematics.types.compound.ModelType'>, so basically each model you added was overwriting the last. I switched it to repr() as a workaround as that keeps the models name in it. Once I've got something working I'll open up a pull request though.