当前位置: 首页 > 后端技术 > Python

TypeError-Objectoftype'datetime'isnotJSONserializable

时间:2023-03-25 21:56:04 Python

pydantic反序列化的坑:TypeError:Objectoftype'datetime'isnotJSONserializable问题描述有如下需求:importrequestsrequests.post('http://localhost/upload/',json=data)data应该是dict类型,data的值不能有detetime类型,如果有datetime,应该转成strfromdatetimeimportdatetime,timezonefromdatetimeimportdatetimefrompydanticimportBaseModel,Fieldimportrequestsimportjsondefget_utc_now_timestamp()->datetime:returndatetime.utcnow().replace(tzinfo=timezone.utc)classStruct(BaseModel):author:str=Field(...)releaseDate:datetime=Field(...)数据=Struct(author='jike',releaseDate=get_utc_now_timestamp())requests.post('http://localhost/upload/',json=data.dict())上面的代码会报错:TypeError:Objectoftype'datetime'不是为什么JSON是可序列化的?因为data应该是一个dict,releaseDate的值应该转换为str而不是datetime,pydantic的dict()只会将releaseDate的值转换为datetime而不是str,所以我们需要修改代码:fromdatetimeimportdatetime,timezonefromdatetimeimportdatetimefrompydanticimportBaseModel,Fieldimportrequestsimportjsondefget_utc_now_timestamp()->日期时间:返回datetime.utcnow().replace(tzinfo=timezone.utc)classStruct(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方法将对象序列化为字符串(pydanticobject->str),然后调用json库的loads方法将字符串反序列化为dict字典。(str->dict)非常复杂,不是吗!不可能!当然,如果你不想在requests中使用,只想序列化成json字符串,可以使用pydantic为你准备的pydantic_encoder,用法如下:fromdatetimeimportdatetime,timezonefromdatetimeimportdatetimefromloguruimportloggerfrompydanticimportBaseModel,Field从pydantic.jsonimportjsonimportpydantic_encoderdefget_utc_now_timestamp()->datetime:returndatetime.utcnow().replace(tzinfo=timezone.utc)classStruct(BaseModel):作者:str=Field(...)releaseDate:datetime=Field(...)data=Struct(author='jike',releaseDate=get_utc_now_timestamp())logger.debug(json.dumps(data.dict(),default=pydantic_encoder))