Skip to content

查询参数

当你声明其他函数参数,而这些参数不是路径参数的一部分时,它们会被自动解释为“查询”参数。

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/

与访问:

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

Check

还要注意,**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

Tip

你也可以像使用 路径参数 那样使用 Enum