Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork8.7k
Comments
Conversation
codecovbot commentedAug 6, 2019 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
Codecov Report
@@ Coverage Diff @@## master #422 +/- ##===================================== Coverage 100% 100% ===================================== Files 240 241 +1 Lines 5626 5642 +16 =====================================+ Hits 5626 5642 +16
Continue to review full report at Codecov.
|
fastapi/routing.py Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
ifisinstance(response,BaseModel):value=response.dict(skip_defaults=skip_defaults)
might also work, but I'm not sure if that would play differently with include/exclude/jsonable_encoder. And givenskip_defaults is probably usually false, I think the version above will be more performant in most cases.
44546a4 toc39a5c8Comparetiangolo commentedAug 26, 2019
Wow, you had to go quite deep into the rabbit hole to find that ( I updated the test to check for defaults in sub-models. And updated the implementation to use And yeah, it's unfortunate to have to do a second parse of the models and have to "clone" models. That came after adding Pydantic ORM mode, as now the data is serialized by Pydantic directly (including DB models). And a sub-model including something sensitive (e.g. a To avoid that security issue, I had to "clone" the models declared in |
Signed-off-by lmignon
Uh oh!
There was an error while loading.Please reload this page.
Addresses#421
Currently, if you return a
BaseModelinstance in a route with aBaseModelresponse_type, theskip_defaultsvalue does not influence the result. This PR fixes this.Details
The source of the problem is that calling
field.validateon a model results in a new model with the fields set. I dug in on the pydantic side and it looks like this is due to the recent change to re-parse the model with a non-subclass type when response_model is set. If you look inBaseModel.validate(which is ultimately called if you follow it deep enough), you can see the precise spot where defaults aren't being skipped:It calls into
parse_objon the last line, which subsequently callsdicton the object and then parses the dict. Unfortunately, this means defaults don't get skipped.I don't think it makes sense to change this on the pydantic side because otherwise you'd run into problems parsing models with default values into non-subclass models with required values. So, if we want to stick with this approach of creating a new class to force a reparse, we probably need to handle the
That said, I would also be in favor of a larger refactor if we could come up with a way to get the desired field safely without another round of parsing/dumping 😬. But that does seem hard.