如何更改get列表的输出,或在FastAPI中使用替代序列化器?



我试图改变FastAPI上的列表视图的内容,取决于get参数。由于格式是由pydantic模型定义的,我如何自定义它(或在视图中使用替代模型)?

这是我的观点:

from fastapi_pagination import Page, Params, paginate
from pydantic import BaseModel
from sqlalchemy.orm import Session

class EventSerializer(BaseModel):
id: str
# ...
class EventAttendeeSerializer(BaseModel):
id: str
event: str  # contains the event UUID
# ...
class Config:
orm_mode = True

@api.get("/", response_model=Page[EventAttendeeSerializer])
async def get_list(db: Session, pagination: Params = Depends(), extend: str = None):
objects = db.query(myDbModel).all()
if "event" in extend.split(","):
# return EventSerializer for each object instead of id

return paginate(objects, pagination)

在运行时,它会像这样工作:

GET /v1/event-attendees/
{
"items": [
{
"id": <event_attendee_id>,
"event": <event_id>,
}
],
"total": 1,
"page": 1,
"size": 50,
}
GET /v1/event-attendees/?extend=event
{
"items": [
{
"id": <event_attendee_id>,
"event": {
"id": <event_id>,
# ...
}
}
],
"total": 1,
"page": 1,
"size": 50,
}

我在pydantic和FastAPI文档和源代码中搜索了一些钩子,但没有找到任何相关的。有人能帮忙吗?

您可以使用Union(两种类型)声明response_model,并在满足条件时返回您希望的模型。因为你正在返回一个对象/模型列表,你可以将response_model声明为UnionList

工作示例

from fastapi import FastAPI
from pydantic import BaseModel
from typing import List, Union

class Simple(BaseModel):
id: int

class Specific(Simple):
description: str

RESULT = {
'id': 1,
'description': 'test'
}

app = FastAPI()

@app.get('/results', response_model=List[Union[Specific, Simple]])
def get_results(specific: bool = False):
if specific:
results = [Specific(**RESULT)] * 2
else:
results = [Simple(**RESULT)] * 2
return results

使用FastAPI 0.89.0+,您可以选择在函数返回类型注释中声明返回类型/response_model,例如:

@app.get('/results')
def get_results(specific: bool = False) -> List[Union[Specific, Simple]]:
if specific:
# ...

至于使用备用序列化器(如你的问题中提到的),请看看这个答案和这个答案。你可以在这个答案中了解FastAPI如何默认序列化返回值。

最新更新