首页 > 其他分享 >FastAPI学习-15.JSON 编码器 jsonable_encoder

FastAPI学习-15.JSON 编码器 jsonable_encoder

时间:2023-09-17 11:15:19浏览次数:35  
标签:编码器 15 FastAPI jsonable encoder item json dict datetime

前言

在某些情况下,您可能需要将数据类型(如Pydantic模型)转换为与JSON兼容的数据类型(如dictlist等)。
比如,如果您需要将其存储在数据库中。
对于这种要求, FastAPI提供了jsonable_encoder()函数。

使用jsonable_encoder

jsonable_encoder

  • 在实际应用场景中,可能需要将数据类型(如:Pydantic 模型)转换为与 JSON 兼容的类型(如:字典、列表)
  • 比如:需要将数据存储在数据库中
  • 为此,FastAPI 提供了一个 jsonable_encoder() 函数
  • jsonable_encoder 实际上是 FastAPI 内部用来转换数据的,但它在许多其他场景中很有用

需求

  • 假设有一个仅接收兼容 JSON 数据的数据库 fake_db
  • 例如,它不接收日期时间对象,因为这些对象与 JSON 不兼容
  • 因此,必须将日期时间对象转换为包含 ISO 格式数据的 str
  • 同样,这个数据库不会接收 Pydantic 模型(具有属性的对象),只会接收 dict
  • 使用 jsonable_encoder 将数据转换成 dict

让我们假设你有一个数据库名为fake_db,它只能接收与 JSON 兼容的数据。

from datetime import datetime  
from typing import Union  
from fastapi import FastAPI  
from pydantic import BaseModel  
  
  
# 模拟数据库  
fake_db = {}  
  
  
class Item(BaseModel):  
    title: str  
    timestamp: datetime  
    description: Union[str, None] = None  
  
  
@app.post("/items/{pk}")  
def update_item(pk: str, item: Item):  
    # 新版2.x item.model_dump() 旧版1.x item.dict()  
    print(f"转成dict类型:{item.dict()}")  
    # 新版2.x item.model_dump_json() 旧版1.x item.json()  
    print(f"转成json类型:{item.json()}")  
    fake_db[pk] = item.dict()  
    print(f"得到数据:{fake_db}")  
    return fake_db

请求接口

POST http://127.0.0.1:8000/items/22 HTTP/1.1
User-Agent: Fiddler
Host: 127.0.0.1:8000
Content-Type: application/json
Content-Length: 86

{
  "title": 22,
  "timestamp": "2023-09-16 10:45:00",
  "description": "描述"
}

运行结果

转成dict类型:{'title': '22', 'timestamp': datetime.datetime(2023, 9, 16, 10, 45), 'description': '描述'}
转成json类型:{"title": "22", "timestamp": "2023-09-16T10:45:00", "description": "\u63cf\u8ff0"}
得到数据:{'22': {'title': '22', 'timestamp': datetime.datetime(2023, 9, 16, 10, 45), 'description': '描述'}}

Pydantic模型可以通过item.dict()转成字典对象 (**新版2.x item.model_dump() 旧版1.x item.dict() ** )

{'title': '22', 'timestamp': datetime.datetime(2023, 9, 16, 10, 45), 'description': '描述'}

由于 timestamp 是 datetime这类的对象,它不能通过json.dumps() 转成 json 对象。
我们想得到标准能转 json的 dict 格式,有 2 种实现方式

    1. item.json() 得到标准 json (**新版2.x item.model_dump_json() 旧版1.x item.json() **)。再使用json.loads()转字典
  • 2.使用jsonable_encoder

方法一:
可以通过

item.item.json()

得到json格式数据

{"title": "22", "timestamp": "2023-09-16T10:45:00", "description": "\u63cf\u8ff0"}

再使用json.loads()转字典

json.loads(item.json())

这样就可以得到可以转json的dict

{'title': '22', 'timestamp': '2023-09-16T10:45:00', 'description': '描述'}

方法二 :

使用fastapi 提供的 内置函数jsonable_encoder

from fastapi.encoders import jsonable_encoder


  
@app.post("/items/{pk}")  
def update_item(pk: str, item: Item):  
    json_item = jsonable_encoder(item)  
    print(f"jsonable_encoder: {json_item}")  
    fake_db[pk] = item.dict()  
    print(f"得到数据:{fake_db}")  
    return fake_db

运行结果

jsonable_encoder: {'title': '22', 'timestamp': '2023-09-16T10:45:00', 'description': '描述'}
得到数据:{'22': {'title': '22', 'timestamp': datetime.datetime(2023, 9, 16, 10, 45), 'description': '描述'}}

在这个例子中,它将Pydantic模型转换为dict,并将datetime转换为str
它将返回一个Python标准数据结构(例如dict),其值和子值都与JSON兼容。
调用它的结果后就可以使用 Python 标准编码中的 json.dumps()

jsonable_encoder实际上是FastAPI内部用来转换数据的。但是它在许多其他场景中也很有用。

标签:编码器,15,FastAPI,jsonable,encoder,item,json,dict,datetime
From: https://www.cnblogs.com/yoyoketang/p/17707950.html

相关文章

  • FastAPI学习-16.响应状态码 status_code
    前言与指定响应模型的方式相同,你也可以在以下任意的_路径操作_中使用 status_code 参数来声明用于响应的HTTP状态码:@app.get()@app.post()@app.put()@app.delete()响应状态码fromfastapiimportFastAPIapp=FastAPI()@app.post("/items/",status_code=201)......
  • FastAPI学习-17.其它响应html,文件,视频或其它
    前言通过我们返回JSON类型的接口会比较多,除了返回JSON格式,还可以响应其它格式的内容JSONResponseContent-Type 会被设置成 application/jsonHTMLResponseContent-Type 会被设置成 text/htmlPlainTextResponse Content-Type 会被设置成text/plainORJSONResp......
  • FastAPI学习-18.Response 返回 XML 格式
    前言假设你想要返回一个 XML响应。你可以把你的XML内容放到一个字符串中,放到一个 Response 中,然后返回。Response自定义返回可以把XML内容放到一个字符串中,放到一个 Response 中,设置media_type="application/xml"fromfastapiimportFastAPI,Responseapp=Fa......
  • FastAPI学习-19.response 参数-修改状态码
    前言假设你想默认返回一个HTTP状态码为“OK”200。但如果数据不存在,你想创建它,并返回一个HTTP状态码为“CREATED”201。但你仍然希望能够使用response_model过滤和转换你返回的数据。对于这些情况,你可以使用一个response`参数。使用 response 参数status_code设置默认状......
  • FastAPI学习-21.response 参数-设置响应Cookies
    前言可以在 路径函数 中定义一个类型为 Response的参数,这样你就可以在这个临时响应对象中设置cookie了。response参数设置cookiesfromfastapiimportFastAPI,Responseapp=FastAPI()@app.post("/cookie-and-object/")defcreate_cookie(response:Response):......
  • FastAPI学习-20.response 参数-设置响应头部
    前言你可以在你的_路径操作函数_中声明一个Response类型的参数。设置响应头部你可以在这个_临时_响应对象中设置头部fromfastapiimportFastAPI,Responseapp=FastAPI()@app.get("/headers-and-object/")defget_headers(response:Response):response.headers......
  • P7215首都
    2023-09-14题目P7215[JOISC2020]首都难度&重要性(1~10):8题目来源luogu题目算法点分治解题思路一个显然的\(O(n^2)\)的暴力思路。因为这是一颗树,我们就每一次将城镇\(1\simn\)定为根节点,将这个城镇的所属城市定为首都,而要求首都的其他城镇到根节点的路径上只有首......
  • Luogu-P4315 月下“毛景树”
    在洛谷中查看前言将边权转化到点权的树剖,很好理解,但我就说说线段树部分。原本想做P1505[国家集训队]旅游的,但是发现它需要边权转化点权,所以先做了这题,于是代码里维护了\(minn\)、\(maxn\)、\(sum\)。包含内容:线段树部分怎么写、本题随机数据生成器线段树怎么写先试着......
  • 「2023/09/15」选拔练习1
    VasyaandaTree题目描述:给定一颗n个点、点带权的树,根节点为1,初始时所有点的点权为0。有m次操作,每次操作给定三元组(v,d,x),将v子树中与v距离不超过d的所有点(包括点v)的点权加x。询问m次操作后所有点的点权。数据范围:\(1\len,m\le3\times10^5\)。做的时候一直在想怎么用树......
  • 9月15日总结
    我刚刚看了一些关于静态数据和静态方法的用法的黑马教程。在静态方法中,只能访问静态成员,而非静态方法可以访问所有成员。静态方法中没有this关键字,它相当于对象调用函数时在函数的空括号内由虚拟机自动编写的调用对象的类型的this,可以看作是一个形参。另外,在一个类中,静态常量只需......