diff --git a/fastapi/encoders.py b/fastapi/encoders.py index 87a9283c0c..f35e4c6767 100644 --- a/fastapi/encoders.py +++ b/fastapi/encoders.py @@ -265,7 +265,8 @@ def jsonable_encoder( sqlalchemy_safe=sqlalchemy_safe, ) - obj_dict = obj.model_dump( + obj_dict = obj.__pydantic_serializer__.to_python( + obj, mode="json", include=include, exclude=exclude, @@ -277,11 +278,8 @@ def jsonable_encoder( ) return jsonable_encoder( obj_dict, - by_alias=by_alias, - exclude_unset=exclude_unset, exclude_none=exclude_none, exclude_defaults=exclude_defaults, - custom_encoder=custom_encoder, sqlalchemy_safe=sqlalchemy_safe, ) obj_dict = obj.model_dump( diff --git a/tests/test_jsonable_encoder.py b/tests/test_jsonable_encoder.py index 4e4614c5d9..ebb7814bfc 100644 --- a/tests/test_jsonable_encoder.py +++ b/tests/test_jsonable_encoder.py @@ -284,6 +284,21 @@ def test_custom_encoder_model_field_uses_caller_options(): ) == {"value": {"required": 1}} +def test_custom_encoder_model_field_does_not_encode_field_names(): + class CustomValue: + pass + + class ModelWithCustomValue(BaseModel): + model_config = ConfigDict(arbitrary_types_allowed=True) + + value: CustomValue + + assert jsonable_encoder( + ModelWithCustomValue(value=CustomValue()), + custom_encoder={CustomValue: lambda _: "encoded", str: str.upper}, + ) == {"value": "ENCODED"} + + def test_custom_enum_encoders(): def custom_enum_encoder(v: Enum): return v.value.lower()