ormar icon indicating copy to clipboard operation
ormar copied to clipboard

Fix add_field_serializer_for_reverse_relations clearing validators

Open camillol opened this issue 9 months ago • 5 comments

When a model has a reverse relation, Ormar synthesizes a field for it. In order to get Pydantic to see the new field, it calls DecoratorInfos.build (in add_field_serializer_for_reverse_relations) to pick up the new serializer, and then model_rebuild. Unfortunately, DecoratorInfos.build is not idempotent. When it processes a model class, it collects the information in __pydantic_decorators__, and it strips out the decorators from the class members, to save time in case it has to process the class again (as the base class of a different class). If it is called again, it starts collecting the decorators from scratch, ignoring the existing __pydantic_decorators__. Since the class members have already had their decorators stripped, they are not collected again. The net result is that any pydantic decorators that had already been processed are lost.

This has the result of ignoring @field_validator etc. if a model has a reverse relation that is processed after the model.

This PR fixes the issue by storing the preexisting __pydantic_decorators__ and merging the new ones into it. This fix should keep working even if Pydantic changes DecoratorInfos.build to be idempotent.

camillol avatar May 14 '24 16:05 camillol