Pydantic说你可以通过简单地定义__get_validators__
方法来创建定制类,如果你想解析成一个有自己元类的类,或者出于其他原因不想继承BaseModel
,这是很有用的。
但是,这在FastAPI中会在奇怪的地方失败,例如FastAPI不会将这样的类检测为主体参数,而总是认为它是查询参数。
from fastapi import FastAPI, Body
from fastapi.testclient import TestClient
app = FastAPI()
class NastyMetaClass(type):
pass
class Foo(metaclass=NastyMetaClass):
@classmethod
def __get_validators__(cls):
yield lambda value: True
@app.post("/implicit")
def foo(foo: Foo): # This is supposed to work, but does not
return "It worked"
@app.post("/explicit")
def foo_body(foo: Foo = Body(...)): # The `= Body(...)` fixes it
return "It worked"
client = TestClient(app)
response = client.post("/implicit", json={})
print(response.json())
# {'detail': [{'loc': ['query', 'foo'], 'msg': 'field required', 'type': 'value_error.missing'}]}
response = client.post("/explicit", json={})
print(response.json())
# It worked
如何让FastAPI识别自定义的Pydantic类?
1条答案
按热度按时间vwkv1x7d1#
根据FastAPI文档,当使用
Body(...)
时,您指示FastAPI将参数视为主体。因此,使用foo: Foo = Body(...)
是告诉端点期望具有Foo
属性的JSON
主体的一种方式。或者,您可以使用Dependencies来删除
Foo
参数,如下所示。您甚至可以简单地使用Depends()
(即foo: Foo = Depends()
)作为避免代码重复的快捷方式。另外,
/implicit
路由需要foo
作为查询参数的原因是,Foo
类不继承自BaseModel
,这将告诉FastAPI将其视为主体。因此,您应该有一个继承自BaseModel
的类,在其中定义foo
参数,并在端点中使用该模型。如Pydantic文档中所示。例如: