乐趣区

关于python:TypeError-Object-of-type-‘datetime‘-is-not-JSON-serializable

pydantic 反序列化的坑:TypeError: Object of type‘datetime‘is not JSON serializable

问题形容

有如下需要:

import requests

requests.post('http://localhost/upload/', json=data)

data 应该是一个 dict 类型

data 的 value 不应该有 detetime 类型,如果有 datetime 应该转为 str

from datetime import datetime, timezone
from datetime import datetime
from pydantic import BaseModel, Field
import requests
import json


def get_utc_now_timestamp() -> datetime:
    return datetime.utcnow().replace(tzinfo=timezone.utc)


class Struct(BaseModel):
    author: str = Field(...)
    releaseDate: datetime = Field(...)


data = Struct(
    author='jike',
    releaseDate=get_utc_now_timestamp())


requests.post('http://localhost/upload/', json=data.dict())

下面的代码会报错:TypeError: Object of type‘datetime‘is not JSON serializable

为什么呢?因为 data 应该是一个 dict,其中的 releaseDate 的 value 应该转为 str,而不能是 datetime

而 pydantic 的 dict() 只会把 releaseDate 的 value 转为 datetime 而不是 str

所以,咱们须要批改代码:

from datetime import datetime, timezone
from datetime import datetime
from pydantic import BaseModel, Field
import requests
import json


def get_utc_now_timestamp() -> datetime:
    return datetime.utcnow().replace(tzinfo=timezone.utc)


class Struct(BaseModel):
    author: str = Field(...)
    releaseDate: datetime = Field(...)


data = Struct(
    author='jike',
    releaseDate=get_utc_now_timestamp()).json(ensure_ascii=False)


requests.post('http://localhost/upload/', json=json.loads(data))

pydantic 模型的 json 会把 datetime 类型的字段转为 str

解决方案就是:

  • 先调用 pydantic 的 json 办法把对象序列化为字符串。(pydantic object -> str)
  • 在调用 json 库的 loads 办法把字符串反序列化为 dict 字典。(str-> dict)

很绕是吧!没方法呢!

退出移动版