FastAPI开发文档教程-查询参数和字符串校验

admin 2026-01-10 10:50:54 编程 来源:ZONE.CI 全球网 0 阅读模式
  • 额外的校验
    • 导入 Query
  • 使用 Query 作为默认值
  • 添加更多校验
  • 添加正则表达式
  • 默认值
  • 声明为必需参数
    • 使用省略号(...)声明必需参数
    • 使用None声明必需参数
    • 使用Pydantic中的Required代替省略号(...)
  • 查询参数列表 / 多个值
    • 具有默认值的查询参数列表 / 多个值
      • 使用 list
  • 声明更多元数据
  • 别名参数
  • 弃用参数
  • 总结

    FastAPI 允许你为参数声明额外的信息和校验。

    让我们以下面的应用程序为例:

    Python 3.10+Python 3.8+

    1. from fastapi import FastAPI
    2. app = FastAPI()
    3. @app.get("/items/")
    4. async def read_items(q: str | None = None):
    5. results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    6. if q:
    7. results.update({"q": q})
    8. return results`
    1. from typing import Union
    2. from fastapi import FastAPI
    3. app = FastAPI()
    4. @app.get("/items/")
    5. async def read_items(q: Union[str, None] = None):
    6. results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    7. if q:
    8. results.update({"q": q})
    9. return results`

    查询参数 q 的类型为 str,默认值为 None,因此它是可选的。

    额外的校验

    我们打算添加约束条件:即使 q 是可选的,但只要提供了该参数,则该参数值不能超过50个字符的长度

    导入 Query

    为此,首先从 fastapi 导入 Query

    1. from typing import Union
    2. from fastapi import FastAPI, Query
    3. app = FastAPI()
    4. @app.get("/items/")
    5. async def read_items(q: Union[str, None] = Query(default=None, max_length=50)):
    6. results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    7. if q:
    8. results.update({"q": q})
    9. return results`

    使用 Query 作为默认值

    现在,将 Query 用作查询参数的默认值,并将它的 max_length 参数设置为 50:

    1. from typing import Union
    2. from fastapi import FastAPI, Query
    3. app = FastAPI()
    4. @app.get("/items/")
    5. async def read_items(q: Union[str, None] = Query(default=None, max_length=50)):
    6. results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    7. if q:
    8. results.update({"q": q})
    9. return results`

    由于我们必须用 Query(default=None) 替换默认值 NoneQuery 的第一个参数同样也是用于定义默认值。

    所以:

    q: Union[str, None] = Query(default=None)

    …使得参数可选,等同于:

    q: str = None

    但是 Query 显式地将其声明为查询参数。

    然后,我们可以将更多的参数传递给 Query。在本例中,适用于字符串的 max_length 参数:

    q: Union[str, None] = Query(default=None, max_length=50)

    将会校验数据,在数据无效时展示清晰的错误信息,并在 OpenAPI 模式的路径操作中记录该参​​数。

    添加更多校验

    你还可以添加 min_length 参数:

    1. from typing import Union
    2. from fastapi import FastAPI, Query
    3. app = FastAPI()
    4. @app.get("/items/")
    5. async def read_items(
    6. q: Union[str, None] = Query(default=None, min_length=3, max_length=50), ):
    7. results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    8. if q:
    9. results.update({"q": q})
    10. return results`

    添加正则表达式

    你可以定义一个参数值必须匹配的正则表达式:

    1. from typing import Union
    2. from fastapi import FastAPI, Query
    3. app = FastAPI()
    4. @app.get("/items/")
    5. async def read_items(
    6. q: Union[str, None] = Query(
    7. default=None, min_length=3, max_length=50, pattern="^fixedquery$" ),
    8. ):
    9. results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    10. if q:
    11. results.update({"q": q})
    12. return results`

    这个指定的正则表达式通过以下规则检查接收到的参数值:

    • ^:以该符号之后的字符开头,符号之前没有字符。
    • fixedquery: 值精确地等于 fixedquery
    • $: 到此结束,在 fixedquery 之后没有更多字符。

    如果你对所有的这些「正则表达式」概念感到迷茫,请不要担心。对于许多人来说这都是一个困难的主题。你仍然可以在无需正则表达式的情况下做很多事情。

    但是,一旦你需要用到并去学习它们时,请了解你已经可以在 FastAPI 中直接使用它们。

    默认值

    你可以向 Query 的第一个参数传入 None 用作查询参数的默认值,以同样的方式你也可以传递其他默认值。

    假设你想要声明查询参数 q,使其 min_length3,并且默认值为 fixedquery

    1. from fastapi import FastAPI, Query
    2. app = FastAPI()
    3. @app.get("/items/")
    4. async def read_items(q: str = Query(default="fixedquery", min_length=3)):
    5. results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    6. if q:
    7. results.update({"q": q})
    8. return results`

    Note

    具有默认值还会使该参数成为可选参数。

    声明为必需参数

    当我们不需要声明额外的校验或元数据时,只需不声明默认值就可以使 q 参数成为必需参数,例如:

    q: str

    代替:

    q: Union[str, None] = None

    但是现在我们正在用 Query 声明它,例如:

    q: Union[str, None] = Query(default=None, min_length=3)

    因此,当你在使用 Query 且需要声明一个值是必需的时,只需不声明默认参数:

    1. from fastapi import FastAPI, Query
    2. app = FastAPI()
    3. @app.get("/items/")
    4. async def read_items(q: str = Query(min_length=3)):
    5. results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    6. if q:
    7. results.update({"q": q})
    8. return results`

    使用省略号(...)声明必需参数

    有另一种方法可以显式的声明一个值是必需的,即将默认参数的默认值设为 ...

    1. from fastapi import FastAPI, Query
    2. app = FastAPI()
    3. @app.get("/items/")
    4. async def read_items(q: str = Query(default=..., min_length=3)):
    5. results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    6. if q:
    7. results.update({"q": q})
    8. return results`

    Info

    如果你之前没见过 ... 这种用法:它是一个特殊的单独值,它是 Python 的一部分并且被称为「省略号」。 Pydantic 和 FastAPI 使用它来显式的声明需要一个值。

    这将使 FastAPI 知道此查询参数是必需的。

    使用None声明必需参数

    你可以声明一个参数可以接收None值,但它仍然是必需的。这将强制客户端发送一个值,即使该值是None

    为此,你可以声明None是一个有效的类型,并仍然使用default=...

    1. from typing import Union
    2. from fastapi import FastAPI, Query
    3. app = FastAPI()
    4. @app.get("/items/")
    5. async def read_items(q: Union[str, None] = Query(default=..., min_length=3)):
    6. results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    7. if q:
    8. results.update({"q": q})
    9. return results`

    Tip

    Pydantic 是 FastAPI 中所有数据验证和序列化的核心,当你在没有设默认值的情况下使用 OptionalUnion[Something, None] 时,它具有特殊行为,你可以在 Pydantic 文档中阅读有关必需可选字段的更多信息。

    使用Pydantic中的Required代替省略号(...)

    如果你觉得使用 ... 不舒服,你也可以从 Pydantic 导入并使用 Required

    1. from fastapi import FastAPI, Query
    2. from pydantic import Required
    3. app = FastAPI()
    4. @app.get("/items/")
    5. async def read_items(q: str = Query(default=Required, min_length=3)):
    6. results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    7. if q:
    8. results.update({"q": q})
    9. return results`

    Tip

    请记住,在大多数情况下,当你需要某些东西时,可以简单地省略 default 参数,因此你通常不必使用 ...Required

    查询参数列表 / 多个值

    当你使用 Query 显式地定义查询参数时,你还可以声明它去接收一组值,或换句话来说,接收多个值。

    例如,要声明一个可在 URL 中出现多次的查询参数 q,你可以这样写:

    1. from typing import List, Union
    2. from fastapi import FastAPI, Query
    3. app = FastAPI()
    4. @app.get("/items/")
    5. async def read_items(q: Union[List[str], None] = Query(default=None)):
    6. query_items = {"q": q}
    7. return query_items`

    然后,输入如下网址:

    http://localhost:8000/items/?q=foo&q=bar

    你会在路径操作函数函数参数 q 中以一个 Python list 的形式接收到查询参数 q 的多个值(foobar)。

    因此,该 URL 的响应将会是:

    { "q": [ "foo", "bar" ] }

    Tip

    要声明类型为 list 的查询参数,如上例所示,你需要显式地使用 Query,否则该参数将被解释为请求体。

    交互式 API 文档将会相应地进行更新,以允许使用多个值:

    查询参数和字符串校验 - 图1

    具有默认值的查询参数列表 / 多个值

    你还可以定义在没有任何给定值时的默认 list 值:

    1. from typing import List
    2. from fastapi import FastAPI, Query
    3. app = FastAPI()
    4. @app.get("/items/")
    5. async def read_items(q: List[str] = Query(default=["foo", "bar"])):
    6. query_items = {"q": q}
    7. return query_items`

    如果你访问:

    http://localhost:8000/items/

    q 的默认值将为:["foo", "bar"],你的响应会是:

    { "q": [ "foo", "bar" ] }

    使用 list

    你也可以直接使用 list 代替 List [str]

    1. from fastapi import FastAPI, Query
    2. app = FastAPI()
    3. @app.get("/items/")
    4. async def read_items(q: list = Query(default=[])):
    5. query_items = {"q": q}
    6. return query_items`

    Note

    请记住,在这种情况下 FastAPI 将不会检查列表的内容。

    例如,List[int] 将检查(并记录到文档)列表的内容必须是整数。但是单独的 list 不会。

    声明更多元数据

    你可以添加更多有关该参数的信息。

    这些信息将包含在生成的 OpenAPI 模式中,并由文档用户界面和外部工具所使用。

    Note

    请记住,不同的工具对 OpenAPI 的支持程度可能不同。

    其中一些可能不会展示所有已声明的额外信息,尽管在大多数情况下,缺少的这部分功能已经计划进行开发。

    你可以添加 title

    1. from typing import Union
    2. from fastapi import FastAPI, Query
    3. app = FastAPI()
    4. @app.get("/items/")
    5. async def read_items(
    6. q: Union[str, None] = Query(default=None, title="Query string", min_length=3), ):
    7. results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    8. if q:
    9. results.update({"q": q})
    10. return results`

    以及 description

    1. from typing import Union
    2. from fastapi import FastAPI, Query
    3. app = FastAPI()
    4. @app.get("/items/")
    5. async def read_items(
    6. q: Union[str, None] = Query(
    7. default=None,
    8. title="Query string",
    9. description="Query string for the items to search in the database that have a good match", min_length=3,
    10. ),
    11. ):
    12. results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    13. if q:
    14. results.update({"q": q})
    15. return results`

    别名参数

    假设你想要查询参数为 item-query

    像下面这样:

    http://127.0.0.1:8000/items/?item-query=foobaritems

    但是 item-query 不是一个有效的 Python 变量名称。

    最接近的有效名称是 item_query

    但是你仍然要求它在 URL 中必须是 item-query

    这时你可以用 alias 参数声明一个别名,该别名将用于在 URL 中查找查询参数值:

    1. from typing import Union
    2. from fastapi import FastAPI, Query
    3. app = FastAPI()
    4. @app.get("/items/")
    5. async def read_items(q: Union[str, None] = Query(default=None, alias="item-query")):
    6. results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    7. if q:
    8. results.update({"q": q})
    9. return results`

    弃用参数

    现在假设你不再喜欢此参数。

    你不得不将其保留一段时间,因为有些客户端正在使用它,但你希望文档清楚地将其展示为已弃用。

    那么将参数 deprecated=True 传入 Query

    1. from typing import Union
    2. from fastapi import FastAPI, Query
    3. app = FastAPI()
    4. @app.get("/items/")
    5. async def read_items(
    6. q: Union[str, None] = Query(
    7. default=None,
    8. alias="item-query",
    9. title="Query string",
    10. description="Query string for the items to search in the database that have a good match",
    11. min_length=3,
    12. max_length=50,
    13. pattern="^fixedquery$",
    14. deprecated=True, ),
    15. ):
    16. results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    17. if q:
    18. results.update({"q": q})
    19. return results`

    文档将会像下面这样展示它:

    查询参数和字符串校验 - 图2

    总结

    你可以为查询参数声明额外的校验和元数据。

    通用的校验和元数据:

    • alias
    • title
    • description
    • deprecated

    特定于字符串的校验:

    • min_length
    • max_length
    • regex

    在这些示例中,你了解了如何声明对 str 值的校验。

    请参阅下一章节,以了解如何声明对其他类型例如数值的校验。

    FastAPI开发文档教程-路径参数 编程

    FastAPI开发文档教程-路径参数

    声明路径参数的类型数据转换数据校验查看文档基于标准的好处,备选文档Pydantic顺序很重要预设值创建 Enum 类声明路径参数查看文档使用 Python 枚举类型比较枚举元素获取枚举值返回枚举元素包
    FastAPI开发文档教程-查询参数 编程

    FastAPI开发文档教程-查询参数

    默认值可选参数查询参数类型转换多个路径和查询参数必选查询参数声明的参数不是路径参数时,路径操作函数会把该参数自动解释为查询参数。 from fastapi import FastAPIapp = Fa
    评论:0   参与:  0