跳至內容

查詢參數

當您宣告非路徑參數的其他函式參數時,它們會自動被解讀為「查詢」參數。

from fastapi import FastAPI

app = FastAPI()

fake_items_db = [{"item_name": "Foo"}, {"item_name": "Bar"}, {"item_name": "Baz"}]


@app.get("/items/")
async def read_item(skip: int = 0, limit: int = 10):
    return fake_items_db[skip : skip + limit]

查詢是指 URL 中位於 ? 之後,以 & 字元分隔的鍵值對集合。

例如,在以下 URL 中:

http://127.0.0.1:8000/items/?skip=0&limit=10

...查詢參數為:

  • skip:值為 0
  • limit:值為 10

由於它們是 URL 的一部分,因此它們「自然地」是字串。

但是,當您使用 Python 類型宣告它們時(在上面的範例中為 int),它們會被轉換為該類型並根據該類型進行驗證。

所有應用於路徑參數的流程也適用於查詢參數:

  • 編輯器支援(顯然地)
  • 資料 "解析"
  • 資料驗證
  • 自動產生文件

預設值

由於查詢參數不是路徑的固定部分,因此它們可以是選用的,並且可以具有預設值。

在上面的範例中,它們的預設值為 skip=0limit=10

因此,前往以下 URL:

http://127.0.0.1:8000/items/

會與前往以下 URL 相同:

http://127.0.0.1:8000/items/?skip=0&limit=10

但如果您前往例如:

http://127.0.0.1:8000/items/?skip=20

則函式中的參數值將會是:

  • skip=20:因為您在 URL 中設定了它
  • limit=10:因為這是預設值

選用參數

同樣地,您可以透過將預設值設定為 None 來宣告選用的查詢參數。

from fastapi import FastAPI

app = FastAPI()


@app.get("/items/{item_id}")
async def read_item(item_id: str, q: str | None = None):
    if q:
        return {"item_id": item_id, "q": q}
    return {"item_id": item_id}
from typing import Union

from fastapi import FastAPI

app = FastAPI()


@app.get("/items/{item_id}")
async def read_item(item_id: str, q: Union[str, None] = None):
    if q:
        return {"item_id": item_id, "q": q}
    return {"item_id": item_id}

在這種情況下,函式參數 q 將是選用的,預設值為 None

檢查

另請注意,**FastAPI** 夠聰明,可以注意到路徑參數 item_id 是一個路徑參數,而 q 不是,所以它是一個查詢參數。

查詢參數類型轉換

您也可以宣告 bool 類型,它們會被轉換。

from fastapi import FastAPI

app = FastAPI()


@app.get("/items/{item_id}")
async def read_item(item_id: str, q: str | None = None, short: bool = False):
    item = {"item_id": item_id}
    if q:
        item.update({"q": q})
    if not short:
        item.update(
            {"description": "This is an amazing item that has a long description"}
        )
    return item
from typing import Union

from fastapi import FastAPI

app = FastAPI()


@app.get("/items/{item_id}")
async def read_item(item_id: str, q: Union[str, None] = None, short: bool = False):
    item = {"item_id": item_id}
    if q:
        item.update({"q": q})
    if not short:
        item.update(
            {"description": "This is an amazing item that has a long description"}
        )
    return item

在這種情況下,如果您前往:

http://127.0.0.1:8000/items/foo?short=1

http://127.0.0.1:8000/items/foo?short=True

http://127.0.0.1:8000/items/foo?short=true

http://127.0.0.1:8000/items/foo?short=on

http://127.0.0.1:8000/items/foo?short=yes

或任何其他大小寫變體(大寫、首字母大寫等),您的函式將會看到參數 shortbool 值為 True。否則為 False

多個路徑和查詢參數

您可以同時宣告多個路徑參數和查詢參數,**FastAPI** 知道哪個是哪個。

而且您不必以任何特定順序宣告它們。

它們會透過名稱被偵測。

from fastapi import FastAPI

app = FastAPI()


@app.get("/users/{user_id}/items/{item_id}")
async def read_user_item(
    user_id: int, item_id: str, q: str | None = None, short: bool = False
):
    item = {"item_id": item_id, "owner_id": user_id}
    if q:
        item.update({"q": q})
    if not short:
        item.update(
            {"description": "This is an amazing item that has a long description"}
        )
    return item
from typing import Union

from fastapi import FastAPI

app = FastAPI()


@app.get("/users/{user_id}/items/{item_id}")
async def read_user_item(
    user_id: int, item_id: str, q: Union[str, None] = None, short: bool = False
):
    item = {"item_id": item_id, "owner_id": user_id}
    if q:
        item.update({"q": q})
    if not short:
        item.update(
            {"description": "This is an amazing item that has a long description"}
        )
    return item

必要的查詢參數

當您為非路徑參數(目前為止,我們只看到查詢參數)宣告預設值時,則該參數不是必要的。

如果您不想新增特定值,只想讓它成為選用參數,請將預設值設定為 None

但是,當您想要讓查詢參數成為必要參數時,您可以不宣告任何預設值。

from fastapi import FastAPI

app = FastAPI()


@app.get("/items/{item_id}")
async def read_user_item(item_id: str, needy: str):
    item = {"item_id": item_id, "needy": needy}
    return item

這裡,查詢參數 needy 是一個必要的 str 類型查詢參數。

如果您在瀏覽器中開啟像這樣的 URL:

http://127.0.0.1:8000/items/foo-item

...而未新增必要的參數 needy,您將會看到類似以下的錯誤:

{
  "detail": [
    {
      "type": "missing",
      "loc": [
        "query",
        "needy"
      ],
      "msg": "Field required",
      "input": null,
      "url": "https://errors.pydantic.dev/2.1/v/missing"
    }
  ]
}

由於 needy 是一個必要的參數,您需要在 URL 中設定它:

http://127.0.0.1:8000/items/foo-item?needy=sooooneedy

...這樣就可以了。

{
    "item_id": "foo-item",
    "needy": "sooooneedy"
}

當然,您可以將某些參數定義為必要的,某些參數具有預設值,而某些參數則完全是選用的。

from fastapi import FastAPI

app = FastAPI()


@app.get("/items/{item_id}")
async def read_user_item(
    item_id: str, needy: str, skip: int = 0, limit: int | None = None
):
    item = {"item_id": item_id, "needy": needy, "skip": skip, "limit": limit}
    return item
from typing import Union

from fastapi import FastAPI

app = FastAPI()


@app.get("/items/{item_id}")
async def read_user_item(
    item_id: str, needy: str, skip: int = 0, limit: Union[int, None] = None
):
    item = {"item_id": item_id, "needy": needy, "skip": skip, "limit": limit}
    return item

在這種情況下,有 3 個查詢參數:

  • needy,一個必要的 str
  • skip,一個預設值為 0int
  • limit,一個選用的 int

提示

您也可以像使用 路徑參數 一樣使用 Enum