FastAPI 教程翻译 – 用户指南 4 – 查询参数 Tutorial – User Guide – Query Parameters

When you declare other function parameters that are not part of the path parameters, they are automatically interpreted as “query” parameters.

声明不属于路径参数的其他视图函数参数时,它们将自动解释为『查询』参数。

1
2
3
4
5
6
7
8
9
10
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]

The query is the set of key-value pairs that go after the ? in a URL, separated by & characters.

查询是一系列的键值对,这些键值对位于 URL 中的 ? 字符之后,并以 & 字符分隔。

For example, in the url:

例如,在如下 URL 中:

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

…the query parameters are:

…… 查询参数如下:

  • skip:with a value of 0 值为 0
  • limit:with a value of 10 值为 10

As they are part of the URL, they are “naturally” strings.

由于它们是 URL 的一部分,因此它们『自然而然』是字符串。

But when you declare them with Python types (in the example above, as int), they are converted to that type and validated against it.

但是,当您使用 Python 类型声明它们时(在上面的示例中为 int),它们将转换为该类型并针对该类型进行验证。

All the same process that applied for path parameters also applies for query parameters:

应用于路径参数的所有过程也适用于查询参数:

  • Editor support (obviously) 编辑器支持(显然)
  • Data “parsing” 数据『解析』
  • Data validation 数据验证
  • Automatic documentation 自动文档

Defaults 默认值

As query parameters are not a fixed part of a path, they can be optional and can have default values.

由于查询参数不是路径的固定部分,因此它们可以是可选的,并且可以具有默认值。

In the example above they have default values of skip=0 and limit=10.

在上面的示例中,它们的默认值为 skip=0limit=10

So, going to the URL:

因此,转到这个 URL:

1
http://127.0.0.1:8000/items/

would be the same as going to:

将与执行以下操作相同:

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

But if you go to, for example:

但是,如果您要去这个 URL:

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

The parameter values in your function will be:

视图函数中的参数值为:

  • skip=20:because you set it in the URL 因为您在 URL 中进行了设置
  • limit=10:because that was the default value 因为那是默认值

Optional parameters 可选查询参数

The same way, you can declare optional query parameters, by setting their default to None:

同样,您可以通过将可选查询参数的默认值设置为 None 来声明可选查询参数:

1
2
3
4
5
6
7
8
9
10
from fastapi import FastAPI

app = FastAPI()


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

In this case, the function parameter q will be optional, and will be None by default.

在这种情况下,视图函数参数 q 将是可选的,默认情况下将为 None

Check 检查

Also notice that FastAPI is smart enough to notice that the path parameter item_id is a path parameter and q is not, so, it’s a query parameter.

还请注意,FastAPI 非常聪明,足以注意到参数 item_id 是路径参数,而 q 不是路径参数,因此它是一个查询参数。

Query parameter type conversion 查询参数类型转换

You can also declare bool types, and they will be converted:

您还可以将查询参数声明为 bool 类型,传入的参数将会被转换:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from fastapi import FastAPI

app = FastAPI()


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

In this case, if you go to:

在这种情况下,如果您要执行以下操作:

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

or

或者

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

or

或者

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

or

或者

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

or

或者

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

or any other case variation (uppercase, first letter in uppercase, etc), your function will see the parameter short with a bool value of True. Otherwise as False.

或任何其他大小写变体(全部大写,首字母大写等),您的函数将会把参数 short 转换为 bool 类型,值为 True,否则为 False

Multiple path and query parameters 多个路径和查询参数

You can declare multiple path parameters and query parameters at the same time, FastAPI knows which is which.

您可以同时声明多个路径参数和查询参数,FastAPI 知道区分它们。

And you don’t have to declare them in any specific order.

而且您不必以任何特定顺序声明它们。

They will be detected by name:

将通过名称检测到它们:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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, 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

Required query parameters 必需的查询参数

When you declare a default value for non-path parameters (for now, we have only seen query parameters), then it is not required.

当您声明非路径参数的默认值时(目前,我们仅看到查询参数),则可以不需要此参数(可选的)。

如果您不想添加特定值,而只是使其成为可选参数,则将默认值设置为 None

If you don’t want to add a specific value but just make it optional, set the default as None.

但是,当您必需一个查询参数时,就不能声明任何默认值:

1
2
3
4
5
6
7
8
9
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

Here the query parameter needy is a required query parameter of type str.

这里的查询参数 needy 是类型为 str 的必需查询参数。

If you open in your browser a URL like:

如果您在浏览器中打开一个 URL,例如:

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

…without adding the required parameter needy, you will see an error like:

…… 未添加必需的参数 needy,您将看到如下的错误:

1
2
3
4
5
6
7
8
9
10
11
12
{
    "detail": [
        {
            "loc": [
                "query",
                "needy"
            ],
            "msg": "field required",
            "type": "value_error.missing"
        }
    ]
}

As needy is a required parameter, you would need to set it in the URL:

由于 needy 是必需参数,因此您需要在 URL 中进行设置:

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

…this would work:

…… 这将实现:

1
2
3
4
{
    "item_id": "foo-item",
    "needy": "sooooneedy"
}

And of course, you can define some parameters as required, some as having a default value, and some entirely optional:

当然,您可以根据需要定义一些参数,一些具有默认值,而某些则完全可选:

1
2
3
4
5
6
7
8
9
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):
    item = {"item_id": item_id, "needy": needy, "skip": skip, "limit": limit}
    return item

In this case, there are 3 query parameters:

在这种情况下,有 3 个查询参数:

  • needy:a required str 必需的 str
  • skip:an int with a default value of 0 默认值为 0int
  • limit:an optional int 可选的 int

Tip 提示

You could also use Enums the same way as with Path Parameters.

您也可以使用 Enum 类,就像 路径参数 一样。

Optional type declarations 可选类型声明

Warning 警告

This might be an advanced use case.

这可能是高级用法。

You might want to skip it.

您可能要跳过它。

If you are using mypy it could complain with type declarations like:

如果您使用的是 mypy,它可能会对如下的类型声明:

1
limit: int = None

With an error like:

会出现这样的错误:

1
Incompatible types in assignment (expression has type "None", variable has type "int")

In those cases you can use Optional to tell mypy that the value could be None, like:

在这种情况下,您可以使用 Optional 来告诉 mypy 该参数的值可以为 None,例如:

1
2
3
from typing import Optional

limit: Optional[int] = None

In a path operation that could look like:

路径操作中,如下方式使用:

1
2
3
4
5
6
7
8
9
10
11
from typing import Optional

from fastapi import FastAPI

app = FastAPI()


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