”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > FastAPI:如何使用 Pydantic 声明查询参数

FastAPI:如何使用 Pydantic 声明查询参数

发布于2024-11-19
浏览:637

它大约三周前发布,是 FastAPI 最受期待的功能之一。至少当我们谈论 Pydantic Models FastAPI 时。

是的,我说的是使用 Pydantic 模型来映射查询参数的能力。

所以在这篇文章中,我将尽力向您展示一切?可以和?无法解决这个问题?:

?映射查询参数

要开始使用 Pydantic 映射查询参数,您需要做的第一件事是确保您使用的是 FastAPI 版本 0.115.0。

此后,您可以随时访问 FastAPI 文档来检查已有的内容。 Sebastián 和团队成员在保持文档更新和信息丰富方面做得非常非常出色 ✨。

?一点点历史

让我们从一些示例开始,了解如何在 FastAPI 中映射查询参数。 ?

最简单的方法是:

from fastapi import FastAPI

app = FastAPI()

@app.get("/")
async def search(
    limit: int | None = 10,
    skip: int | None = 1,
    filter: str | None = None
):
    return {
        "limit": limit,
        "skip": skip,
        "filter": filter
    }

现在您只需调用:

GET http://localhost:8000/?limit=42&skip=12&filter=banana

但是,如果我们确定此查询参数将在其他路由中使用,我们将使用以下内容隔离它:

from typing import Any
from fastapi import Depends, FastAPI, Query

app = FastAPI()

async def pagination_query_string(
    limit: int | None = Query(10, ge=5, le=100),
    skip: int | None = Query(1, ge=1),
    filter: str | None = Query(None)
) -> dict[str, Any]:
    return {
        "limit": limit,
        "skip": skip,
        "filter": filter
    }

@app.get("/")
async def search(q: dict[str, Any] = Depends(pagination_query_string)):
    return q

或者因为我们使用 Pydantic 来映射我们的模型,只需一点重构,我们就会得到:

from fastapi import Depends, FastAPI, Query
from pydantic import BaseModel

app = FastAPI()

class PaginationQueryString(BaseModel):
    limit: int | None = 10
    skip: int | None = 1
    filter: str | None = None

async def pagination_query_string(
    limit: int | None = Query(10, ge=5, le=100),
    skip: int | None = Query(1, ge=1),
    filter: str | None = Query(None)
) -> PaginationQueryString:
    return PaginationQueryString(
        limit=limit,
        skip=skip,
        filter=filter
    )

@app.get("/")
async def search(q: PaginationQueryString = Depends(pagination_query_string)):
    return q

⌨️ 使用 Pydantic 映射查询字符串

FastAPI: How to use Pydantic to declare Query Parameters

现在,如果我们想要获取查询字符串,我们不需要创建一个函数,然后将其添加为依赖项。我们可以简单地告诉 FastAPI 我们想要一个 PaginationQueryString 类型的对象,并且它是一个查询字符串:

from typing import Annotated
from fastapi import FastAPI, Query
from pydantic import BaseModel

app = FastAPI()

class PaginationQueryString(BaseModel):
    limit: int | None = 10
    skip: int | None = 1
    filter: str | None = None

@app.get("/")
async def search(q: Annotated[PaginationQueryString, Query()]):
    return q

简单吧? ?

⚠️有什么限制?

至少在 0.115.0 版本中,它不能很好地处理嵌套模型。

让我们尝试一下:

from typing import Annotated
from fastapi import FastAPI, Query
from pydantic import BaseModel

app = FastAPI()

class Filter(BaseModel):
    name: str | None = None
    age: int | None = None
    nickname: str | None = None

class PaginationQueryString(BaseModel):
    limit: int | None = 10
    skip: int | None = 1
    filter: Filter | None = None

@app.get("/")
async def search(q: Annotated[PaginationQueryString, Query()]):
    return q

如果我们像以前那样称呼它:

GET http://localhost:8000/?limit=42&skip=12&filter=chocolate

我们会收到一个错误,告诉我们过滤器是一个对象:

{
    "detail": [
        {
            "type": "model_attributes_type",
            "loc": [
                "query",
                "filter"
            ],
            "msg": "Input should be a valid dictionary or object to extract fields from",
            "input": "chocolate"
        }
    ]
}

至少现在来说,是绝对正确的!我们将过滤器更改为 Pydantic 模型,而不是字符串。但如果我们尝试将其转换为字典:

http://localhost:8000/?limit=42&skip=12&filter={"name": "Rafael", "age": 38, "nickname": "ceb10n"}

FastAPI 会告诉我们过滤器需要是一个有效的字典?:

{
    "detail": [
        {
            "type": "model_attributes_type",
            "loc": [
                "query",
                "filter"
            ],
            "msg": "Input should be a valid dictionary or object to extract fields from",
            "input": "{\"name\": \"Rafael\", \"age\": 38, \"nickname\": \"ceb10n\"}"
        }
    ]
}

发生这种情况是因为 FastAPI 将依赖 Starlette 的 QueryParams,它将向 FastAPI 提供一个字符串,而不是一个字典。至少在 0.115.0 版本中,这会给你一个错误。

⁉️ 那么,我什么时候应该在查询参数中使用 Pydantic 模型?

这很简单:

✅ 您有简单的查询字符串,不需要任何复杂的花哨的嵌套对象?使用它! ?

❌ 您创建了一个复杂的嵌套查询字符串?还没用过吗? (也许您应该尝试重新考虑您的查询字符串。?越简单越好?)

版本声明 本文转载于:https://dev.to/ceb10n/fastapi-how-to-use-pydantic-to-declare-query-parameters-25bd?1如有侵犯,请联系[email protected]删除
最新教程 更多>
  • 如何使用 MySQL 查找今天生日的用户?
    如何使用 MySQL 查找今天生日的用户?
    如何使用 MySQL 识别今天生日的用户使用 MySQL 确定今天是否是用户的生日涉及查找生日匹配的所有行今天的日期。这可以通过一个简单的 MySQL 查询来实现,该查询将存储为 UNIX 时间戳的生日与今天的日期进行比较。以下 SQL 查询将获取今天有生日的所有用户: FROM USERS ...
    编程 发布于2024-11-19
  • 如何修复 macOS 上 Django 中的“配置不正确:加载 MySQLdb 模块时出错”?
    如何修复 macOS 上 Django 中的“配置不正确:加载 MySQLdb 模块时出错”?
    MySQL配置不正确:相对路径的问题在Django中运行python manage.py runserver时,可能会遇到以下错误:ImproperlyConfigured: Error loading MySQLdb module: dlopen(/Library/Python/2.7/site-...
    编程 发布于2024-11-19
  • ## JavaScript 可以检测浏览器历史记录的可用性吗?
    ## JavaScript 可以检测浏览器历史记录的可用性吗?
    如何检测浏览器历史记录可用性确定浏览器中的后退按钮是否可用是 Web 开发过程中常见的问题。然而,需要注意的是,使用 JavaScript 直接检查浏览器历史记录通常是不可能实现的。技术方法:history.previous技术上,一种方法是利用History.previous 属性。该属性应该指示...
    编程 发布于2024-11-19
  • 如何添加查询字符串来获取 GET 请求?
    如何添加查询字符串来获取 GET 请求?
    使用 Fetch GET 请求的查询字符串Fetch API 提供了一种在 JavaScript 中发出 HTTP 请求的现代方法。默认情况下,使用 Fetch 发出的 GET 请求不包含查询字符串参数。要将查询字符串添加到 GET 请求,我们可以使用 URLSearchParams 接口或手动连接...
    编程 发布于2024-11-19
  • 为什么在选择子集时应该始终复制 Pandas DataFrame?
    为什么在选择子集时应该始终复制 Pandas DataFrame?
    了解 Pandas 中数据帧复制的重要性在 Pandas 中,选择数据帧的一部分时,通常的做法是使用 '.copy() ' 方法创建原始数据帧的副本。此方法可确保对子集所做的任何更改都不会影响父数据框。为什么要进行复制?默认情况下,索引数据框会返回原始数据框的视图,而不是副本。这意味...
    编程 发布于2024-11-19
  • 为什么在 C++ 中 `std::remove` 会重新排列元素而不是删除它们?
    为什么在 C++ 中 `std::remove` 会重新排列元素而不是删除它们?
    理解差异:擦除与删除在 C 编程领域,std::erase 和 std::remove 是两个在修改容器时,不同的功能有不同的用途。虽然这两个函数都可用于从容器中删除元素,但它们的行为有所不同。Std::remove:重新排列元素与删除Std::删除是一种对一系列元素进行操作并在容器内重新排列它们的...
    编程 发布于2024-11-19
  • 我可以依靠 PHP 的“php.ini”精度来进行准确的资金计算吗?
    我可以依靠 PHP 的“php.ini”精度来进行准确的资金计算吗?
    我可以依靠 PHP php.ini 精度解决方案来解决浮点问题吗?简介浮点运算是一个经常被误解的复杂主题,它遍布现代计算机系统。由于大多数小数缺乏精确的二进制表示,因此不可避免地会发生舍入。了解浮点运算的细微差别至关重要,如“每个计算机科学家应该了解的浮点算术知识”中所述。问题与解答问题 1:我可以...
    编程 发布于2024-11-19
  • 委托如何增强 C++ 代码的灵活性和可维护性?
    委托如何增强 C++ 代码的灵活性和可维护性?
    解释 C 中委托的通用概念 C 中的委托是一种编程结构,允许您将函数指针作为参数传递。这使您能够创建可以异步调用或在不同上下文中调用的回调。在 C 中实现委托有多种方法,包括:函子函子是对象定义了一个operator()函数,有效地使它们可调用。struct Functor { int op...
    编程 发布于2024-11-19
  • 如何在 Java 中创建动态命名对象?
    如何在 Java 中创建动态命名对象?
    使用字符串派生变量名称动态创建对象当尝试使用动态生成的名称创建对象时,Java 严格的变量命名规则可能看起来很有限。然而,这种明显的限制实际上是 Java 关注变量引用以及变量名称的重要性相对减弱的结果。虽然 PHP 等脚本语言允许创建具有字符串派生名称的变量,但 Java 采用了不同的方法。 Ja...
    编程 发布于2024-11-19
  • 你应该在 JavaScript 中使用自增和自减运算符吗?
    你应该在 JavaScript 中使用自增和自减运算符吗?
    JavaScript 中增量和减量运算符的争议jslint 工具警告不要使用增量 ( ) 和减量 (-- )运营商出于各种原因。然而,反对这些运算符的论点有些争议。反对 and 的论点 --jslint 工具特别指出,and -- 鼓励“过度狡猾”和已知会导致安全漏洞。此外,PHP 构造 $foo[...
    编程 发布于2024-11-19
  • 如何使用 Python 从网站中提取每日日出/日落时间?
    如何使用 Python 从网站中提取每日日出/日落时间?
    使用 Python 进行网页抓取问:使用 Python 从网站中提取每日日出/日落时间您确实可以利用 Python 的强大功能来抓取 Web 内容并从中提取日出/日落时间等数据websites.Python 提供了一套全面的模块来促进网络抓取。让我们探讨一些关键选项:可用模块:urllib2: 提供...
    编程 发布于2024-11-19
  • 为什么不能直接在 Go 中使用带有类型约束的接口?
    为什么不能直接在 Go 中使用带有类型约束的接口?
    接口类型约束开发 Go 应用程序时,了解接口类型约束所施加的限制至关重要。具有类型元素的接口类型(例如联合)的使用受到限制。本文深入研究了接口类型约束的细节,并提供了示例来说明其影响。​​使用类型约束定义接口在 Go 中,包含类型元素(例如联合)的接口被考虑非基本。这意味着它们不能用作变量的类型或作...
    编程 发布于2024-11-19
  • Bootstrap 4 Beta 中的列偏移发生了什么?
    Bootstrap 4 Beta 中的列偏移发生了什么?
    Bootstrap 4 Beta:列偏移的删除和恢复Bootstrap 4 在其 Beta 1 版本中引入了重大更改柱子偏移了。然而,随着 Beta 2 的后续发布,这些变化已经逆转。从 offset-md-* 到 ml-auto在 Bootstrap 4 Beta 1 中, offset-md-*...
    编程 发布于2024-11-19
  • 如何使用Python在Linux下截屏?
    如何使用Python在Linux下截屏?
    在 Linux 上使用 Python 轻松截取屏幕截图对于那些寻求通过 Python 脚本轻松捕获屏幕截图的便捷方法的人来说,本指南提供了专为 Linux 环境设计的有效解决方案。Pythonic Sc​​reenshot Master为了实现这种屏幕截图能力,Python 利用其与 X Windo...
    编程 发布于2024-11-19
  • 如何使用 jQuery 实时动态更改 CSS 类规则?
    如何使用 jQuery 实时动态更改 CSS 类规则?
    使用 jQuery 动态更改 CSS 类规则您的查询涉及两个方面:1。实时修改类规则仅靠 jQuery 无法动态更改 CSS 类规则。但是,您可以利用文档对象的 styleSheets 属性直接访问 CSS 规则。代码:document.getElementById("button&quo...
    编程 发布于2024-11-19

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3