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

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

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

它大约三周前发布,是 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]删除
最新教程 更多>
  • ReqWeb新版本即将发布:期待的功能更新
    ReqWeb新版本即将发布:期待的功能更新
    当我开始开发reqweb时,我的目标很简单:创建一个强大的,轻巧的Web应用程序防火墙(WAF),任何人都可以用来保护其Web应用程序。随着时间的流逝,它已成长为可靠的解决方案,应对IP过滤,速率限制,基于规则的阻塞以及通过实时警报进行记录等挑战。现在,下一个大型飞跃是Reqweb 2.0即将到来...
    编程 发布于2025-04-18
  • 如何解决Python脚本中的“非ASCII字符”错误?
    如何解决Python脚本中的“非ASCII字符”错误?
    "Non-ASCII Characters" Errors in Python ScriptsWhen working with text that contains non-ASCII characters in Python, errors like "Syntax...
    编程 发布于2025-04-18
  • 如何使用替换指令在GO MOD中解析模块路径差异?
    如何使用替换指令在GO MOD中解析模块路径差异?
    在使用GO MOD时,在GO MOD 中克服模块路径差异时,可能会遇到冲突,其中3个Party Package将另一个PAXPANCE带有导入式套件之间的另一个软件包,并在导入式套件之间导入另一个软件包。如回声消息所证明的那样: go.etcd.io/bbolt [&&&&&&&&&&&&&&&&...
    编程 发布于2025-04-18
  • 左连接为何在右表WHERE子句过滤时像内连接?
    左连接为何在右表WHERE子句过滤时像内连接?
    左JOIN CONUNDRUM:WITCHING小时在数据库Wizard的领域中变成内在的加入很有趣,当将c.foobar条件放置在上面的Where子句中时,据说左联接似乎会转换为内部连接。仅当满足A.Foo和C.Foobar标准时,才会返回结果。为什么要变形?关键在于其中的子句。当左联接的右侧值...
    编程 发布于2025-04-18
  • 哪种在JavaScript中声明多个变量的方法更可维护?
    哪种在JavaScript中声明多个变量的方法更可维护?
    在JavaScript中声明多个变量:探索两个方法在JavaScript中,开发人员经常遇到需要声明多个变量的需要。对此的两种常见方法是:在单独的行上声明每个变量: 当涉及性能时,这两种方法本质上都是等效的。但是,可维护性可能会有所不同。 第一个方法被认为更易于维护。每个声明都是其自己的语句,使其...
    编程 发布于2025-04-18
  • Flexbox中边距与标准CSS布局的区别
    Flexbox中边距与标准CSS布局的区别
    在flexbox 问题:non-flexbox vs. flexbox margins According to the CSS Box Model specification:"A flex container establishes a new flex formatting...
    编程 发布于2025-04-18
  • LINQ方法中哪些保持数组顺序,哪些不保持?
    LINQ方法中哪些保持数组顺序,哪些不保持?
    LINQ 与数组顺序:详解哪些方法保持顺序,哪些方法不保持 在对已排序数组使用 LINQ to Objects 操作时,务必注意避免破坏原始数组顺序的操作。以下分析将为您提供指导: 绝对保持顺序的方法: AsEnumerable: Cast: Concat: Select: ToArray: To...
    编程 发布于2025-04-18
  • 如何从Python中的字符串中删除表情符号:固定常见错误的初学者指南?
    如何从Python中的字符串中删除表情符号:固定常见错误的初学者指南?
    从python import codecs import codecs import codecs 导入 text = codecs.decode('这狗\ u0001f602'.encode('utf-8'),'utf-8') 印刷(文字)#带有...
    编程 发布于2025-04-18
  • 我可以将加密从McRypt迁移到OpenSSL,并使用OpenSSL迁移MCRYPT加密数据?
    我可以将加密从McRypt迁移到OpenSSL,并使用OpenSSL迁移MCRYPT加密数据?
    将我的加密库从mcrypt升级到openssl 问题:是否可以将我的加密库从McRypt升级到OpenSSL?如果是这样,如何?答案:是的,可以将您的Encryption库从McRypt升级到OpenSSL。可以使用openssl。附加说明: [openssl_decrypt()函数要求iv参...
    编程 发布于2025-04-18
  • 如何高效地在一个事务中插入数据到多个MySQL表?
    如何高效地在一个事务中插入数据到多个MySQL表?
    mySQL插入到多个表中,该数据可能会产生意外的结果。虽然似乎有多个查询可以解决问题,但将从用户表的自动信息ID与配置文件表的手动用户ID相关联提出了挑战。使用Transactions和last_insert_id() 插入用户(用户名,密码)值('test','test...
    编程 发布于2025-04-18
  • 如何从Google API中检索最新的jQuery库?
    如何从Google API中检索最新的jQuery库?
    从Google APIS 问题中提供的jQuery URL是版本1.2.6。对于检索最新版本,以前有一种使用特定版本编号的替代方法,它是使用以下语法:获取最新版本:未压缩)While these legacy URLs still remain in use, it is recommended ...
    编程 发布于2025-04-18
  • 在Python中如何创建动态变量?
    在Python中如何创建动态变量?
    在Python 中,动态创建变量的功能可以是一种强大的工具,尤其是在使用复杂的数据结构或算法时,Dynamic Variable Creation的动态变量创建。 Python提供了几种创造性的方法来实现这一目标。利用dictionaries 一种有效的方法是利用字典。字典允许您动态创建密钥并分...
    编程 发布于2025-04-18
  • CSS强类型语言解析
    CSS强类型语言解析
    您可以通过其强度或弱输入的方式对编程语言进行分类的方式之一。在这里,“键入”意味着是否在编译时已知变量。一个例子是一个场景,将整数(1)添加到包含整数(“ 1”)的字符串: result = 1 "1";包含整数的字符串可能是由带有许多运动部件的复杂逻辑套件无意间生成的。它也可以是故意从单个真理...
    编程 发布于2025-04-18
  • 如何限制动态大小的父元素中元素的滚动范围?
    如何限制动态大小的父元素中元素的滚动范围?
    在交互式接口中实现垂直滚动元素的CSS高度限制问题:考虑一个布局,其中我们具有与用户垂直滚动一起移动的可滚动地图div,同时与固定的固定sidebar保持一致。但是,地图的滚动无限期扩展,超过了视口的高度,阻止用户访问页面页脚。$("#map").css({ marginT...
    编程 发布于2025-04-18
  • CSS选择器排除特定类名方法
    CSS选择器排除特定类名方法
    在CSS选择器中排除特定的类名,在某些实例中,您可能需要将特定的类名为选择器中的特定类名为。当您想将样式应用于多个元素时,这一点特别有用,但是某些元素不应继承这些样式。一个常见的方案涉及排除具有特定类名称的元素,同时将样式应用于具有其他类名称的元素。让我们考虑以下示例: 设计 态 ...
    编程 发布于2025-04-18

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

Copyright© 2022 湘ICP备2022001581号-3