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
|
||||
if isinstance(obj, 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():
|
||||
if (
|
||||
(
|
||||
|
|
@ -88,7 +93,7 @@ def jsonable_encoder(
|
|||
or (not key.startswith("_sa"))
|
||||
)
|
||||
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(
|
||||
key,
|
||||
|
|
@ -144,6 +149,8 @@ def jsonable_encoder(
|
|||
raise ValueError(errors)
|
||||
return jsonable_encoder(
|
||||
data,
|
||||
include=include,
|
||||
exclude=exclude,
|
||||
by_alias=by_alias,
|
||||
exclude_unset=exclude_unset,
|
||||
exclude_defaults=exclude_defaults,
|
||||
|
|
|
|||
|
|
@ -93,16 +93,42 @@ def fixture_model_with_path(request):
|
|||
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():
|
||||
person = Person(name="Foo")
|
||||
pet = Pet(owner=person, name="Firulais")
|
||||
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():
|
||||
person = DictablePerson(name="Foo")
|
||||
pet = DictablePet(owner=person, name="Firulais")
|
||||
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():
|
||||
|
|
@ -144,6 +170,14 @@ def test_encode_model_with_default():
|
|||
assert jsonable_encoder(model, exclude_unset=True, exclude_defaults=True) == {
|
||||
"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():
|
||||
|
|
|
|||
Loading…
Reference in New Issue