IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> python:Fastapi 请求体-嵌套模型 -> 正文阅读

[Python知识库]python:Fastapi 请求体-嵌套模型

请求体 - 字段

字段与使用?QueryPath?和?Body?在路径操作函数中声明额外的校验和元数据的方式相同,可以使用?Pydantic?的?Field?在?Pydantic?模型内部声明校验和元数据。

注意点:Field?是直接从?pydantic?导入的,而不是像其他的(QueryPathBody?等)都从?fastapi?导入。

首先导入Field:

from?pydantic?import?Field

其次开始声明模型定义字段:

from?pydantic?import?Field,?BaseModel


class?Items(BaseModel):
????name:?str
????full_name:?Optional[str]?=?Field(None,?min_length=2)
????description:?Optional[str]?=?Field(None,?max_length=100)
????price:?float?=?Field(...,?gt=0)
????gender:?str?=?Field(...,?alias="g")
????tax:?int?=?Field(None,?title="用于文档中",?description="在文档中显示")

注释信息:

  • min_length=2?是设置字段的最小长度
  • max_length=100?是设置字段最大长度
  • gt=0 是大于0?[?ge大于等于、lt小于、le小于等于]
  • alias="g"?是取别名
  • title="用于文档中"?显示在生成的docs文档中
  • description="在文档中显示"?显示在生成的docs文档中

然后开始定义接口:

from?typing?import?Optional
from?fastapi?import?FastAPI
from?fastapi?import?Body
from?pydantic?import?Field,?BaseModel


class?Items(BaseModel):
????name:?str
????full_name:?Optional[str]?=?Field(None,?min_length=2)
????description:?Optional[str]?=?Field(None,?max_length=100)
????price:?float?=?Field(...,?gt=0)
????gender:?str?=?Field(...,?alias="g")
????tax:?int?=?Field(None,?title="用于文档中",?description="在文档中显示")


app?=?FastAPI()


@app.put("/items/{item_id}")
def?read_field(item_id:?int,?item:?Items?=?Body(...,?embed=True)):
????return?{"item_id":?item_id,?"item":?item}

然后启动服务:

lifeng@192?fastapiProject?%?uvicorn?field_main:app?--reload
INFO:?????Will?watch?for?changes?in?these?directories:?['/Users/lifeng/python-projects/python-code/fastapiProject']
INFO:?????Uvicorn?running?on?http://127.0.0.1:8000?(Press?CTRL+C?to?quit)
INFO:?????Started?reloader?process?[45277]?using?statreload
INFO:?????Started?server?process?[45279]
INFO:?????Waiting?for?application?startup.
INFO:?????Application?startup?complete.
WARNING:??StatReload?detected?file?change?in?'field_main.py'.?Reloading...
INFO:?????Shutting?down
INFO:?????Waiting?for?application?shutdown.
INFO:?????Application?shutdown?complete.
INFO:?????Finished?server?process?[45279]
INFO:?????Started?server?process?[45376]
INFO:?????Waiting?for?application?startup.
INFO:?????Application?startup?complete.
INFO:?????127.0.0.1:55549?-?"PUT?/items/1?HTTP/1.1"?200?OK

最后请求接口:

PUT :http://127.0.0.1:8000/items/1

传入请求参数:

{
????"item":?{
????????"name":?"haha",
????????"price":?2.8,
????????"g":?"eee"
????}
}

返回响应结果:

{
????"item_id":?1,
????"item":?{
????????"name":?"haha",
????????"full_name":?null,
????????"description":?null,
????????"price":?2.8,
????????"g":?"eee",
????????"tax":?null
????}
}

请求体 - 嵌套模型

就是给属性(字段)定义为拥有子元素的类型,如:name: list?或?name: List),还有就是嵌套子模型(可以直接理解为字段又嵌套一个子字段),如:image: Optional[Image] = None等。

from?fastapi?import?FastAPI
from?typing?import?Optional,?List,?Set
from?pydantic?import?BaseModel,?Field


class?Image(BaseModel):
????url:?str
????name:?str


class?User(BaseModel):
????name:?str
????full_name:?Optional[str]?=?Field(None)
????age:?int?=?Field(...,?ge=0)
????tags:?List[str]?=?[]
????email:?Set[str]?=?set()
????image:?Image


app?=?FastAPI()


@app.put("/items/{item_id}")
def?read_items(item_id:?int,?user:?User):
????results?=?{"item_id":?item_id,?"user":?user}
????return?results

上述例子User就是声明的模型,Image也是声明的模型,只是Image用在User中,故被称为子模型(嵌套模型),是image属性(字段)拥有的子元素的类型

  • tagsemail是属性含子类型的类型
  • image属于子模型用作类型
  • email属性定义为集合的原因,是可以过滤重复值,保证唯一值,但是在传参时,按列表类型传即可

请求接口:

PUT :http://127.0.0.1:8000/items/1

请求参数:

{
????"name":?"haha",
????"age":?11,
????"tags":?[
????????"1",
????????"2"
????],
????"email":?[
????????"1",
????????"2"
????],
????"image":?{
????????"url":?"http://example.com/baz.jpg",
????????"name":?"heihei"
????}
}

请求结果:

{
????"item_id":?1,
????"user":?{
????????"name":?"haha",
????????"full_name":?null,
????????"age":?11,
????????"tags":?[
????????????"1",
????????????"2"
????????],
????????"email":?[
????????????"1",
????????????"2"
????????],
????????"image":?{
????????????"url":?"http://example.com/baz.jpg",
????????????"name":?"heihei"
????????}
????}
}

如果你遇到字段需要定义为url,就像这样的:

from?pydantic?import?BaseModel


class?Image(BaseModel):
????url:?str
????name:?str

那就直接把url声明为HttpUrl,而不是声明为str

from?pydantic?import?BaseModel,?HttpUrl


class?Image(BaseModel):
????url:?HttpUrl
????name:?str

因为声明为HttpUrl,该字符串将被检查是否为有效的?URL,若检查出不是有效的URL,则抛出异常:

{
????"detail":?[
????????{
????????????"loc":?[
????????????????"body",
????????????????"image",
????????????????"url"
????????????],
????????????"msg":?"invalid?or?missing?URL?scheme",
????????????"type":?"value_error.url.scheme"
????????}
????]
}

有些时候可能会遇到要在子参数中传数组,数组中要传多个参数,那这个时候就需要给子模型定义类型,也称子模型的属性:

from?fastapi?import?FastAPI
from?typing?import?List
from?pydantic?import?BaseModel,?Field,?HttpUrl


class?Image(BaseModel):
????url:?HttpUrl
????name:?str


class?User(BaseModel):
????name:?str
????age:?int?=?Field(...,?ge=0)
????images:?List[Image]


app?=?FastAPI()


@app.put("/items/{item_id}")
def?read_items(item_id:?int,?user:?User):
????results?=?{"item_id":?item_id,?"user":?user}
????return?results

请求接口:

PUT :http://127.0.0.1:8000/items/1

请求参数:

{
????"name":?"haha",
????"age":?11,
????"images":?[
????????{
????????????"url":?"http://example.com/baz.jpg",
????????????"name":?"heihei"
????????},
????????{
????????????"url":?"http://example.com/baz.jpg",
????????????"name":?"heihei"
????????},
????????{
????????????"url":?"http://example.com/baz.jpg",
????????????"name":?"heihei"
????????}
????]
}

请求结果:

{
????"item_id":?1,
????"user":?{
????????"name":?"haha",
????????"age":?11,
????????"images":?[
????????????{
????????????????"url":?"http://example.com/baz.jpg",
????????????????"name":?"heihei"
????????????},
????????????{
????????????????"url":?"http://example.com/baz.jpg",
????????????????"name":?"heihei"
????????????},
????????????{
????????????????"url":?"http://example.com/baz.jpg",
????????????????"name":?"heihei"
????????????}
????????]
????}
}

你还可以自定义任意深度的嵌套模型:

from?fastapi?import?FastAPI
from?typing?import?List,?Optional,?Set
from?pydantic?import?BaseModel,?HttpUrl

app?=?FastAPI()


class?Image(BaseModel):
????url:?HttpUrl
????name:?str


class?Item(BaseModel):
????name:?str
????description:?Optional[str]?=?None
????price:?float
????tax:?Optional[float]?=?None
????tags:?Set[str]?=?set()
????images:?List[Image]


class?Offer(BaseModel):
????name:?str
????description:?Optional[str]?=?None
????price:?float
????items:?List[Item]


@app.post("/items/")
async?def?read_items(offer:?Offer):
????return?offer

请求接口:

POST :http://127.0.0.1:8000/items

请求参数:

{
????"name":?"haha",
????"price":?3.9,
????"items":?[
????????{
????????????"name":?"heihei",
????????????"price":?4.99,
????????????"tags":?[
????????????????1,
????????????????2,
????????????????3,
????????????????3,
????????????????3,
????????????????3
????????????],
????????????"images":?[
????????????????{
????????????????????"url":?"http://example.com/baz.jpg",
????????????????????"name":?"heihei"
????????????????}
????????????]
????????}
????]
}

请求结果:

{
????"name":?"haha",
????"description":?null,
????"price":?3.9,
????"items":?[
????????{
????????????"name":?"heihei",
????????????"description":?null,
????????????"price":?4.99,
????????????"tax":?null,
????????????"tags":?[
????????????????"1",
????????????????"3",
????????????????"2"
????????????],
????????????"images":?[
????????????????{
????????????????????"url":?"http://example.com/baz.jpg",
????????????????????"name":?"heihei"
????????????????}
????????????]
????????}
????]
}

从请求结果可以看到,请求参数中的tags是一个数组,其实在接口中是一个集合,集合有去重功能,所以返回的结果自然就只有一个3了。


今天先聊到这里吧,以上总结或许能帮助到你,或许帮助不到你,但还是希望能帮助到你,如有疑问、歧义,直接私信留言会及时修正发布;非常期待你的一键 3 连【 点赞、收藏、分享 】哟,谢谢!

未完成,待续……

一直在努力,希望你也是!

微信搜索公众号:就用python

  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2022-02-14 21:05:39  更:2022-02-14 21:07:17 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 23:37:21-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码