【FAST API】請求體 - 多個參數


 

既然我們已經知道了如何使用 Path 和 Query,下面讓我們來了解一下請求體聲明的更高級用法。

混合使用 PathQuery 和請求體參數

首先,毫無疑問地,你可以隨意地混合使用 PathQuery 和請求體參數聲明,FastAPI 會知道該如何處理。

你還可以通過將默認值設置為 None 來將請求體參數聲明為可選參數:

from typing import Optional

from fastapi import FastAPI, Path
from pydantic import BaseModel

app = FastAPI()


class Item(BaseModel):
    name: str
    description: Optional[str] = None
    price: float
    tax: Optional[float] = None


@app.put("/items/{item_id}")
async def update_item(
    *,
    item_id: int = Path(..., title="The ID of the item to get", ge=0, le=1000),
    q: Optional[str] = None,
    item: Optional[Item] = None,
):
    results = {"item_id": item_id}
    if q:
        results.update({"q": q})
    if item:
        results.update({"item": item})
    return results

 

請注意,在這種情況下,將從請求體獲取的 item 是可選的。因為它的默認值為 None

多個請求體參數

在上面的示例中,路徑操作將期望一個具有 Item 的屬性的 JSON 請求體,就像:

{
    "name": "Foo",
    "description": "The pretender",
    "price": 42.0,
    "tax": 3.2
}

 

但是你也可以聲明多個請求體參數,例如 item 和 user

from typing import Optional

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()


class Item(BaseModel):
    name: str
    description: Optional[str] = None
    price: float
    tax: Optional[float] = None


class User(BaseModel):
    username: str
    full_name: Optional[str] = None


@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item, user: User):
    results = {"item_id": item_id, "item": item, "user": user}
    return results

 

在這種情況下,FastAPI 將注意到該函數中有多個請求體參數(兩個 Pydantic 模型參數)。

因此,它將使用參數名稱作為請求體中的鍵(字段名稱),並期望一個類似於以下內容的請求體:

{
    "item": {
        "name": "Foo",
        "description": "The pretender",
        "price": 42.0,
        "tax": 3.2
    },
    "user": {
        "username": "dave",
        "full_name": "Dave Grohl"
    }
}

 

請注意,即使 item 的聲明方式與之前相同,但現在它被期望通過 item 鍵內嵌在請求體中。

FastAPI 將自動對請求中的數據進行轉換,因此 item 參數將接收指定的內容,user 參數也是如此。

它將執行對復合數據的校驗,並且像現在這樣為 OpenAPI 模式和自動化文檔對其進行記錄。

請求體中的單一值

與使用 Query 和 Path 為查詢參數和路徑參數定義額外數據的方式相同,FastAPI 提供了一個同等的 Body

例如,為了擴展先前的模型,你可能決定除了 item 和 user 之外,還想在同一請求體中具有另一個鍵 importance

如果你就按原樣聲明它,因為它是一個單一值,FastAPI 將假定它是一個查詢參數。

但是你可以使用 Body 指示 FastAPI 將其作為請求體的另一個鍵進行處理。

from typing import Optional

from fastapi import Body, FastAPI
from pydantic import BaseModel

app = FastAPI()


class Item(BaseModel):
    name: str
    description: Optional[str] = None
    price: float
    tax: Optional[float] = None


class User(BaseModel):
    username: str
    full_name: Optional[str] = None


@app.put("/items/{item_id}")
async def update_item(
    item_id: int, item: Item, user: User, importance: int = Body(...)
):
    results = {"item_id": item_id, "item": item, "user": user, "importance": importance}
    return results

 

在這種情況下,FastAPI 將期望像這樣的請求體:

{
    "item": {
        "name": "Foo",
        "description": "The pretender",
        "price": 42.0,
        "tax": 3.2
    },
    "user": {
        "username": "dave",
        "full_name": "Dave Grohl"
    },
    "importance": 5
}

 

同樣的,它將轉換數據類型,校驗,生成文檔等。

多個請求體參數和查詢參數

當然,除了請求體參數外,你還可以在任何需要的時候聲明額外的查詢參數。

由於默認情況下單一值被解釋為查詢參數,因此你不必顯式地添加 Query,你可以僅執行以下操作:

q: str = None

 

比如:

from typing import Optional

from fastapi import Body, FastAPI
from pydantic import BaseModel

app = FastAPI()


class Item(BaseModel):
    name: str
    description: Optional[str] = None
    price: float
    tax: Optional[float] = None


class User(BaseModel):
    username: str
    full_name: Optional[str] = None


@app.put("/items/{item_id}")
async def update_item(
    *,
    item_id: int,
    item: Item,
    user: User,
    importance: int = Body(..., gt=0),
    q: Optional[str] = None
):
    results = {"item_id": item_id, "item": item, "user": user, "importance": importance}
    if q:
        results.update({"q": q})
    return results

 

Body 同樣具有與 QueryPath 以及其他后面將看到的類完全相同的額外校驗和元數據參數。

嵌入單個請求體參數

假設你只有一個來自 Pydantic 模型 Item 的請求體參數 item

默認情況下,FastAPI 將直接期望這樣的請求體。

但是,如果你希望它期望一個擁有 item 鍵並在值中包含模型內容的 JSON,就像在聲明額外的請求體參數時所做的那樣,則可以使用一個特殊的 Body 參數 embed

item: Item = Body(..., embed=True)

 

比如:

from typing import Optional

from fastapi import Body, FastAPI
from pydantic import BaseModel

app = FastAPI()


class Item(BaseModel):
    name: str
    description: Optional[str] = None
    price: float
    tax: Optional[float] = None


@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item = Body(..., embed=True)):
    results = {"item_id": item_id, "item": item}
    return results

 

在這種情況下,FastAPI 將期望像這樣的請求體:

{
    "item": {
        "name": "Foo",
        "description": "The pretender",
        "price": 42.0,
        "tax": 3.2
    }
}

 

而不是:

{
    "name": "Foo",
    "description": "The pretender",
    "price": 42.0,
    "tax": 3.2
}

 

總結

你可以添加多個請求體參數到路徑操作函數中,即使一個請求只能有一個請求體。

但是 FastAPI 會處理它,在函數中為你提供正確的數據,並在路徑操作中校驗並記錄正確的模式。

你還可以聲明將作為請求體的一部分所接收的單一值。

你還可以指示 FastAPI 在僅聲明了一個請求體參數的情況下,將原本的請求體嵌入到一個鍵中。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM