Fastapi: [FEATURE] Add request_model_include/exclude

Created on 30 Apr 2020  路  9Comments  路  Source: tiangolo/fastapi

I have a model that include an ID field, which I return in responses. However, in requests (when POSTing new instances), I don't want the user to be able to specify the ID.

Similarly to how we can include/exclude fields in the response, we should be able to exclude fields in the request. Declaring more classes just to exclude specific fields is a bit cumbersome, and making the property optional is semantically wrong, since I don't want to let the user specify it at all.

enhancement

Most helpful comment

Yes, exactly, this is the rationale for the PR, so we can avoid having three different models just to exclude three fields. That's a bit clunky, whereas this solution is much more elegant and is symmetrical with the response include/exclude.

All 9 comments

Sure, but it feels dirty and unsemantic to have to create different models for each field you want to include, and is asymmetric with response_model_exclude existing.

Is there any reason you can't default the ID to None in the pydantic model?

Yes, the ID is not optional, it must not be sent at all.

As far as I can see, this would just require passing the exclude list straight to any calls to models.to_dict right? (as seen here). I should have a bit of time this weekend to give it a go.

I think it's a bit more complicated than that, because the request is also for docs/requests, not just responses. I might have misunderstood what you mean, though, @Lunrtick, please correct me if so.

I was talking about excluding it in the request, but you're right, it's definitely more complicated than just skipping the property in serialisation (mostly because of needing it to be documented in openapi). I was hoping to see how the response_model is translated to the openapi schema. I'd imagine that it wouldn't necessarily make sense to have a different Schema entry simply to exclude an ID?

To be clear, I'd probably want the list of Schemas to contain a User, for example, like this

{
    "id": "integer",
    "email": "string",
    "password": "string",
    "created_at": "datetime",
    "updated_at": "datetime"
}

And then on a particular route (maybe the create route), I'd exclude the "id", "created_at", and "updated_at" keys. So the schema for this route would then just be

{
    "email": "string",
    "password": "string"
}

This wouldn't require a separate pydantic model, so the global list of schemas would only have a User, not a UserInDB + UserToCreate + UserOut etc.

Yes, exactly, this is the rationale for the PR, so we can avoid having three different models just to exclude three fields. That's a bit clunky, whereas this solution is much more elegant and is symmetrical with the response include/exclude.

I think this also fits well with the OpenAPI 3.0 spec's Read-Only and Write-Only Properties. response_exclude maps well to writeOnly openapi property and a potential request_exclude would map nicely to the readOnly openapi property.
However, I think that feature implementation might suit Pydantic better and have fastapi read off it.

Was this page helpful?
0 / 5 - 0 ratings