mirror of https://github.com/tiangolo/fastapi.git
🐛 Fix `jsonable_encoder` using `include` and `exclude` parameters for non-Pydantic objects (#2606)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
This commit is contained in:
parent
8a9a117ec7
commit
eb2e183361
|
|
@ -80,6 +80,11 @@ def jsonable_encoder(
|
||||||
return obj
|
return obj
|
||||||
if isinstance(obj, dict):
|
if isinstance(obj, dict):
|
||||||
encoded_dict = {}
|
encoded_dict = {}
|
||||||
|
allowed_keys = set(obj.keys())
|
||||||
|
if include is not None:
|
||||||
|
allowed_keys &= set(include)
|
||||||
|
if exclude is not None:
|
||||||
|
allowed_keys -= set(exclude)
|
||||||
for key, value in obj.items():
|
for key, value in obj.items():
|
||||||
if (
|
if (
|
||||||
(
|
(
|
||||||
|
|
@ -88,7 +93,7 @@ def jsonable_encoder(
|
||||||
or (not key.startswith("_sa"))
|
or (not key.startswith("_sa"))
|
||||||
)
|
)
|
||||||
and (value is not None or not exclude_none)
|
and (value is not None or not exclude_none)
|
||||||
and ((include and key in include) or not exclude or key not in exclude)
|
and key in allowed_keys
|
||||||
):
|
):
|
||||||
encoded_key = jsonable_encoder(
|
encoded_key = jsonable_encoder(
|
||||||
key,
|
key,
|
||||||
|
|
@ -144,6 +149,8 @@ def jsonable_encoder(
|
||||||
raise ValueError(errors)
|
raise ValueError(errors)
|
||||||
return jsonable_encoder(
|
return jsonable_encoder(
|
||||||
data,
|
data,
|
||||||
|
include=include,
|
||||||
|
exclude=exclude,
|
||||||
by_alias=by_alias,
|
by_alias=by_alias,
|
||||||
exclude_unset=exclude_unset,
|
exclude_unset=exclude_unset,
|
||||||
exclude_defaults=exclude_defaults,
|
exclude_defaults=exclude_defaults,
|
||||||
|
|
|
||||||
|
|
@ -93,16 +93,42 @@ def fixture_model_with_path(request):
|
||||||
return ModelWithPath(path=request.param("/foo", "bar"))
|
return ModelWithPath(path=request.param("/foo", "bar"))
|
||||||
|
|
||||||
|
|
||||||
|
def test_encode_dict():
|
||||||
|
pet = {"name": "Firulais", "owner": {"name": "Foo"}}
|
||||||
|
assert jsonable_encoder(pet) == {"name": "Firulais", "owner": {"name": "Foo"}}
|
||||||
|
assert jsonable_encoder(pet, include={"name"}) == {"name": "Firulais"}
|
||||||
|
assert jsonable_encoder(pet, exclude={"owner"}) == {"name": "Firulais"}
|
||||||
|
assert jsonable_encoder(pet, include={}) == {}
|
||||||
|
assert jsonable_encoder(pet, exclude={}) == {
|
||||||
|
"name": "Firulais",
|
||||||
|
"owner": {"name": "Foo"},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def test_encode_class():
|
def test_encode_class():
|
||||||
person = Person(name="Foo")
|
person = Person(name="Foo")
|
||||||
pet = Pet(owner=person, name="Firulais")
|
pet = Pet(owner=person, name="Firulais")
|
||||||
assert jsonable_encoder(pet) == {"name": "Firulais", "owner": {"name": "Foo"}}
|
assert jsonable_encoder(pet) == {"name": "Firulais", "owner": {"name": "Foo"}}
|
||||||
|
assert jsonable_encoder(pet, include={"name"}) == {"name": "Firulais"}
|
||||||
|
assert jsonable_encoder(pet, exclude={"owner"}) == {"name": "Firulais"}
|
||||||
|
assert jsonable_encoder(pet, include={}) == {}
|
||||||
|
assert jsonable_encoder(pet, exclude={}) == {
|
||||||
|
"name": "Firulais",
|
||||||
|
"owner": {"name": "Foo"},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def test_encode_dictable():
|
def test_encode_dictable():
|
||||||
person = DictablePerson(name="Foo")
|
person = DictablePerson(name="Foo")
|
||||||
pet = DictablePet(owner=person, name="Firulais")
|
pet = DictablePet(owner=person, name="Firulais")
|
||||||
assert jsonable_encoder(pet) == {"name": "Firulais", "owner": {"name": "Foo"}}
|
assert jsonable_encoder(pet) == {"name": "Firulais", "owner": {"name": "Foo"}}
|
||||||
|
assert jsonable_encoder(pet, include={"name"}) == {"name": "Firulais"}
|
||||||
|
assert jsonable_encoder(pet, exclude={"owner"}) == {"name": "Firulais"}
|
||||||
|
assert jsonable_encoder(pet, include={}) == {}
|
||||||
|
assert jsonable_encoder(pet, exclude={}) == {
|
||||||
|
"name": "Firulais",
|
||||||
|
"owner": {"name": "Foo"},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def test_encode_unsupported():
|
def test_encode_unsupported():
|
||||||
|
|
@ -144,6 +170,14 @@ def test_encode_model_with_default():
|
||||||
assert jsonable_encoder(model, exclude_unset=True, exclude_defaults=True) == {
|
assert jsonable_encoder(model, exclude_unset=True, exclude_defaults=True) == {
|
||||||
"foo": "foo"
|
"foo": "foo"
|
||||||
}
|
}
|
||||||
|
assert jsonable_encoder(model, include={"foo"}) == {"foo": "foo"}
|
||||||
|
assert jsonable_encoder(model, exclude={"bla"}) == {"foo": "foo", "bar": "bar"}
|
||||||
|
assert jsonable_encoder(model, include={}) == {}
|
||||||
|
assert jsonable_encoder(model, exclude={}) == {
|
||||||
|
"foo": "foo",
|
||||||
|
"bar": "bar",
|
||||||
|
"bla": "bla",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def test_custom_encoders():
|
def test_custom_encoders():
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue