我有使用Fast API 的代码,看起来像这样:
class EnumTestT(Enum):
test_t_value = 0
object = {
test: test_t_value
}
enum_mapping = {
test_t_value: "Test"
}
def enum_encoder(val: EnumTestT) -> str:
return enum_mapping[val]
custom_encoder = {
EnumTestT: enum_encoder
}
@app.get("/test")
async def test_get():
return jsonable_encoder(object, custom_encoder=custom_encoder)
Run Code Online (Sandbox Code Playgroud)
问题是jsonable_encoder在默认编码器之后应用自定义编码器。有什么方法可以在默认编码器之前应用它们。因为对于Enum任何派生类,报告的是枚举值而不是映射值。
FastAPI 使用 ENCODERS_BY_TYPE (来自 pydantic.json)来编码一些基本数据类型。
ENCODERS_BY_TYPE: Dict[Type[Any], Callable[[Any], Any]] = {
bytes: lambda o: o.decode(),
Color: str,
datetime.date: isoformat,
datetime.datetime: isoformat,
datetime.time: isoformat,
datetime.timedelta: lambda td: td.total_seconds(),
Decimal: decimal_encoder,
Enum: lambda o: o.value,
Run Code Online (Sandbox Code Playgroud)
所以对我来说要覆盖默认的日期时间编码,就像
ENCODERS_BY_TYPE[datetime] = lambda date_obj: date_obj.strftime("%Y-%m-%d %H:%M:%S")
Run Code Online (Sandbox Code Playgroud)
现在我正在使用自定义编码器,json.dumps如下所示:
class TestEncoder(JSONEncoder):
def default(self, obj):
if isinstance(obj, EnumTestT):
return TestEncoder.process_enum_test_t(obj)
Run Code Online (Sandbox Code Playgroud)
FastAPI 应用程序内的响应将是:
json_str = json.dumps(json_list, cls=TestEncoder).encode('utf-8')
return Response(media_type="application/json", content=json_str)
Run Code Online (Sandbox Code Playgroud)
使用自定义编码器的 FastAPI 的问题在于,在调用所有标准编码器之后才调用自定义编码器,并且无法覆盖该顺序。