schematics icon indicating copy to clipboard operation
schematics copied to clipboard

Using multiple Model as alterantive?

Open cnicodeme opened this issue 7 years ago • 3 comments

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 avatar Apr 27 '18 16:04 cnicodeme

@cnicodeme Did you ever figure out a workaround to this?

naphta avatar Sep 27 '18 09:09 naphta

@naphta No. When I'll have the time, I'll write my own library. Expect it to be ready around the year 2521

cnicodeme avatar Sep 27 '18 09:09 cnicodeme

@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.

naphta avatar Sep 27 '18 10:09 naphta