FastAPI教程 查詢參數(shù)

2021-11-02 14:48 更新

聲明不屬于路徑參數(shù)的其他函數(shù)參數(shù)時(shí),它們將被自動(dòng)解釋為"查詢字符串"參數(shù)

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]

查詢字符串是鍵值對(duì)的集合,這些鍵值對(duì)位于 URL 的 ?? 之后,并以 ??符號(hào)分隔。

例如,在以下 url 中:

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

...查詢參數(shù)為:

  • skip:對(duì)應(yīng)的值為 0
  • limit:對(duì)應(yīng)的值為 10

由于它們是 URL 的一部分,因此它們的"原始值"是字符串。

但是,當(dāng)你為它們聲明了 Python 類型(在上面的示例中為 ?int?)時(shí),它們將轉(zhuǎn)換為該類型并針對(duì)該類型進(jìn)行校驗(yàn)。

應(yīng)用于路徑參數(shù)的所有相同過程也適用于查詢參數(shù):

  • (很明顯的)編輯器支持
  • 數(shù)據(jù)"解析"
  • 數(shù)據(jù)校驗(yàn)
  • 自動(dòng)生成文檔

默認(rèn)值

由于查詢參數(shù)不是路徑的固定部分,因此它們可以是可選的,并且可以有默認(rèn)值。

在上面的示例中,它們具有 skip=0 和 limit=10 的默認(rèn)值。

因此,訪問 URL:

http://127.0.0.1:8000/items/

將與訪問以下地址相同:

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

但是,如果你訪問的是:

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

函數(shù)中的參數(shù)值將會(huì)是:

  • skip=20:在 URL 中設(shè)定的值
  • limit=10:使用默認(rèn)值

可選參數(shù)

通過同樣的方式,你可以將它們的默認(rèn)值設(shè)置為 ?None ?來聲明可選查詢參數(shù):

from typing import Optional

from fastapi import FastAPI

app = FastAPI()


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

在這個(gè)例子中,函數(shù)參數(shù) ??將是可選的,并且默認(rèn)值為 ?None?。

還要注意的是,F(xiàn)astAPI 足夠聰明,能夠分辨出參數(shù) ?item_id? 是路徑參數(shù)而 ??不是,因此 ??是一個(gè)查詢參數(shù)。

查詢參數(shù)類型轉(zhuǎn)換

你還可以聲明 ?bool ?類型,它們將被自動(dòng)轉(zhuǎn)換:

from typing import Optional

from fastapi import FastAPI

app = FastAPI()


@app.get("/items/{item_id}")
async def read_item(item_id: str, q: Optional[str] = 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

這個(gè)例子中,如果你訪問:

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

或任何其他的變體形式(大寫,首字母大寫等等),你的函數(shù)接收的 ?short ?參數(shù)都會(huì)是布爾值 ?True?。對(duì)于值為 ?False ?的情況也是一樣的。

多個(gè)路徑和查詢參數(shù)

你可以同時(shí)聲明多個(gè)路徑參數(shù)和查詢參數(shù),FastAPI 能夠識(shí)別它們。

而且你不需要以任何特定的順序來聲明。

它們將通過名稱被檢測(cè)到:

from typing import Optional

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: Optional[str] = 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

必需查詢參數(shù)

當(dāng)你為非路徑參數(shù)聲明了默認(rèn)值時(shí)(目前而言,我們所知道的僅有查詢參數(shù)),則該參數(shù)不是必需的。

如果你不想添加一個(gè)特定的值,而只是想使該參數(shù)成為可選的,則將默認(rèn)值設(shè)置為 ?None?。

但當(dāng)你想讓一個(gè)查詢參數(shù)成為必需的,不聲明任何默認(rèn)值就可以:

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

這里的查詢參數(shù) ?needy ?是類型為 ?str? 的必需查詢參數(shù)。

如果你在瀏覽器中打開一個(gè)像下面的 URL:

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

...因?yàn)闆]有添加必需的參數(shù) ?needy?,你將看到類似以下的錯(cuò)誤:

{
    "detail": [
        {
            "loc": [
                "query",
                "needy"
            ],
            "msg": "field required",
            "type": "value_error.missing"
        }
    ]
}

由于 ?needy ?是必需參數(shù),因此你需要在 URL 中設(shè)置它的值:

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

...這樣就正常了:

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

當(dāng)然,你也可以定義一些參數(shù)為必需的,一些具有默認(rèn)值,而某些則完全是可選的:

from typing import Optional

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: Optional[int] = None
):
    item = {"item_id": item_id, "needy": needy, "skip": skip, "limit": limit}
    return item

在這個(gè)例子中,有3個(gè)查詢參數(shù):

  • needy,一個(gè)必需的 str 類型參數(shù)。
  • skip,一個(gè)默認(rèn)值為 0 的 int 類型參數(shù)。
  • limit,一個(gè)可選的 int 類型參數(shù)。

Tip

你還可以像在 路徑參數(shù) 中那樣使用 Enum。


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)