如何更改列表的输出或在 FastAPI 中使用备用序列化器?

问题描述 投票:0回答:1

我正在尝试根据查询参数更改 FastAPI 上列表视图的内容。由于格式是由 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 文档和源代码中搜索了某种钩子,但没有找到任何相关内容。 有人可以帮忙吗?

python fastapi crud pydantic
1个回答
1
投票

您可以使用response_model

(两种类型)对
Union
进行
贴花,并在满足条件时返回您想要的模型。由于您返回的是对象/模型列表,因此您可以将
response_model
声明为
List
Union

工作示例

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 默认情况下如何序列化返回值。

© www.soinside.com 2019 - 2024. All rights reserved.