带alias的输入模型无法通过FastAPI的response_model完成输出转换?
问题
当输入模型包含带别名(alias)的字段,而输出模型无该别名时,FastAPI是否仍能通过response_model隐式转换输出数据?以下示例中出现了验证错误,问题出在哪里?
验证错误信息
1 validation error for OutModel
response -> foo
field required (type=value_error.missing)
示例代码
import fastapi import starlette.testclient from pydantic import BaseModel, Field app = fastapi.FastAPI() class DbModel(BaseModel): foo: str = Field(alias='bar') class OutModel(BaseModel): foo: str @app.get('/test', response_model=OutModel) def test(): foo = DbModel(bar="foo") print(foo.dict()) # {'foo': 'foo'} return foo with starlette.testclient.TestClient(app) as test_client: try: print(test_client.get('/test').json()) except Exception as exc: print(exc)
原因与解决方案
问题根源
FastAPI处理response_model时,会直接对返回的Pydantic模型实例进行序列化校验,而非先调用.dict()方法。虽然foo.dict()输出是{'foo': 'foo'},但FastAPI内部会优先读取模型的原始数据(包括别名相关的内部结构),而非直接使用.dict()的结果。带别名的DbModel实例内部保留了别名字段的映射关系,FastAPI转换为OutModel时,无法正确识别foo字段的实际值,导致校验失败。
解决方法
有两种简单的修复方式:
- 返回模型的
.dict()结果,让FastAPI基于字典数据完成response_model转换:
@app.get('/test', response_model=OutModel) def test(): foo = DbModel(bar="foo") return foo.dict()
- 在
DbModel中添加model_config = {'populate_by_name': True}配置,让模型支持通过字段名而非别名读取值:
class DbModel(BaseModel): model_config = {'populate_by_name': True} foo: str = Field(alias='bar') @app.get('/test', response_model=OutModel) def test(): foo = DbModel(bar="foo") return foo
两种方式都能让FastAPI正确将DbModel实例转换为OutModel的输出格式,返回{"foo": "foo"}。
内容的提问来源于stack exchange,提问作者Kjell-Bear
相关产品推荐
相关产品推荐

