Один из потоков моего приложения требует, чтобы я отправил полезную нагрузку из внешнего интерфейса в серверная часть, где одно из полей имеет множество вариантов. Эту полезную нагрузку необходимо проверить с помощью pydantic на серверной стороне. Для этого я решил использовать дискриминируемое объединение.
Предположим, что класс структурирован таким образом.
Код: Выделить всё
class ClassA(pydantic.BaseModel):
type: Literal["a"]
field_a: int
class ClassB(pydantic.BaseModel):
type: Literal["b"]
...
ClassUnion = Annotated[Union[ClassA, ClassB], pydantic.Field(discriminator="type")]
class Parent(pydantic.BaseModel):
child: ClassUnion
field_parent: str
Для этого у меня есть собственный обработчик ошибок, который перехватывает любую ошибку RequestValidationError из FastAPI, преобразует различные ошибки из ValidationError pydantic в более простую форму. Детали обработчика ошибок не имеют значения; важно то, что обработчик ошибок зависит от поля «loc» в ValidationError.
Например, если ошибка возникает в «field_parent», то поле «loc» будет указывать на место ошибки; это существо («body», «field_parent»). Обратите внимание, что «тело» — это именно то место, где произошла ошибка в запросе FastAPI. Для простоты мы можем предположить, что loc — это просто ("field_parent").
Однако, если в "field_a" встречается loc, то я ожидаю, что loc должен быть: ("child ", "поле_а"). Таким образом, я могу преобразовать поле в форму, соответствующую введенным данным:
Код: Выделить всё
{
"child": {
"field_a": "Error message"
}
}
Есть ли способ удалить значение дискриминатора из поля loc?< /strong> Я не нашел ни одной опции, которая могла бы отключить это поведение (если его вообще можно отключить) в документации по дискриминируемому объединению FastAPI. Это не проблема настройки ошибок проверки запросов FastAPI; а скорее проблема с тем, как Pydantic форматирует поле «loc».
Альтернативные решения:
- Я' Я рассматривал возможность использования WrapValidators для перехвата ValidationError и последующего его изменения, но документации о внутреннем устройстве ValidationError мало (просмотр кода Python тоже не помогает, так как он, вероятно, реализован где-то еще).
- Фильтрация распознаваемых значений объединения вручную кажется грязным решением, к тому же существует риск того, что дискриминатор будет иметь то же имя, что и поле, поэтому я тоже отказался от этого.
- Я не могу просто настроить проверку ошибок для одного или двух маршрутов, поскольку модель будет повторно использоваться на нескольких маршрутах.
Подробнее здесь: https://stackoverflow.com/questions/791 ... onerror-lo